Skip to content

Instantly share code, notes, and snippets.

@yoshiki
Created January 7, 2016 08:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yoshiki/5477fd89b508333f3213 to your computer and use it in GitHub Desktop.
Save yoshiki/5477fd89b508333f3213 to your computer and use it in GitHub Desktop.
import Data.Char (ord)
import Data.Bits
base64 :: String -> String
base64 "" = ""
base64 xs = indexToChar (concat24Bits xs) ++ padding xs
concat24Bits :: String -> [Int]
concat24Bits (x:[]) =
let n = shiftL (ord x::Int) 16
in split6Bits 1 n
concat24Bits (x:y:[]) =
let n = shiftL (ord x::Int) 16 .|. shiftL (ord y::Int) 8
in split6Bits 2 n
concat24Bits (x:y:z:[]) =
let n = shiftL (ord x::Int) 16 .|. shiftL (ord y::Int) 8 .|. ord z
in split6Bits 3 n
concat24Bits (x:y:z:rest) =
let n = shiftL (ord x::Int) 16 .|. shiftL (ord y::Int) 8 .|. ord z
in split6Bits 3 n ++ concat24Bits rest
split6Bits :: Int -> Int -> [Int]
split6Bits 1 n = [shiftR n 18 .&. 63] ++ [shiftR n 12 .&. 63]
split6Bits 2 n = split6Bits 1 n ++ [shiftR n 6 .&. 63]
split6Bits 3 n = split6Bits 2 n ++ [n .&. 63]
indexToChar :: [Int] -> String
indexToChar xs =
let table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
in [ table !! n | n <- xs ]
padding :: String -> String
padding xs =
let p = length xs `mod` 3
in case p of 0 -> ""
1 -> "=="
2 -> "="
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment