Skip to content

Instantly share code, notes, and snippets.

@fizruk
Last active March 4, 2017 09:41
Show Gist options
  • Save fizruk/0b049254874bba5f3ccc0cf2e4c5663d to your computer and use it in GitHub Desktop.
Save fizruk/0b049254874bba5f3ccc0cf2e4c5663d to your computer and use it in GitHub Desktop.
Base64 encoded UUIDs safe for URLs (YouTube style)
import Data.Char (chr, ord)
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Base64 as Base64
import qualified Data.UUID as UUID
-- | Base64 encoded UUID (YouTube style for safe usage in URLs).
newtype Base64UUID = Base64UUID UUID deriving (Show, Eq)
toText :: Base64UUID -> Text
toText = escape (Text.dropEnd 2 (Text.decodeUtf8 (Base64.encode (BL.toStrict (UUID.toByteString uuid)))))
where
escape = Text.replace "+" "-" . Text.replace "/" "_"
fromText :: Text -> Maybe Base64UUID
fromText t = do
let bs64 = Text.encodeUtf8 (unescape t <> "==")
case Base64.decode bs64 of
Left _ -> Nothing
Right bs -> Base64UUID <$> UUID.fromByteString (BL.fromStrict bs)
where
unescape = Text.replace "-" "+" . Text.replace "_" "/"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment