Skip to content

Instantly share code, notes, and snippets.

@rmalecki
Created May 5, 2016 20:34
Show Gist options
  • Save rmalecki/87e0566bca167cdd20c52de44090a3ca to your computer and use it in GitHub Desktop.
Save rmalecki/87e0566bca167cdd20c52de44090a3ca to your computer and use it in GitHub Desktop.
import Data.Bits
import Data.Word
base64Chars = zip [(0::Word8)..] "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
getFst ((b,c):xs) a = if a == b then c else getFst xs a
getBase64Char = getFst base64Chars
encodeTriple :: Word8 -> Word8 -> Word8 -> String
encodeTriple a b c =
map getBase64Char $ zipWith (.|.)
(map transform [(a, -2, 0x3f), (a, 4, 0x30), (b, 2, 0x3c), (c, 0, 0x3f)])
(map transform [(0, 0, 0), (b, -4, 0x0f), (c, -6, 0x03), (0, 0, 0)])
where
transform (a, s, m) = a `shift` s .&. m
bytesToBase64 :: [Word8] -> String
bytesToBase64 [] = []
bytesToBase64 [a] = take 2 (encodeTriple a 0 0) ++ "=="
bytesToBase64 [a, b] = take 3 (encodeTriple a b 0) ++ "="
bytesToBase64 (a:b:c:xs) = encodeTriple a b c ++ bytesToBase64 xs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment