41 lines
1.3 KiB
Haskell
41 lines
1.3 KiB
Haskell
--Decodes Base64 to ASCII
|
|
import qualified Data.Map.Strict as Map (Map, lookup, fromList)
|
|
import Data.Maybe (fromJust, listToMaybe, mapMaybe)
|
|
import Numeric (readInt, showIntAtBase)
|
|
import Data.Char (chr, digitToInt)
|
|
import Data.List.Split (chunksOf)
|
|
|
|
byteToASCII :: String -> String
|
|
byteToASCII = map chr . decoder
|
|
|
|
--generates list of bytes (represented by Int)
|
|
decoder :: String -> [Int]
|
|
decoder =
|
|
map readBin .
|
|
takeWhile (\x -> length x == 8) .
|
|
chunksOf 8 . concatMap toBin . mapMaybe (`Map.lookup` table) . filter (/= '=')
|
|
|
|
--turns decimal into a list of char that represents a binary number
|
|
toBin :: Int -> String
|
|
toBin n = leftPad $ showIntAtBase 2 ("01" !!) n ""
|
|
|
|
--this adds all the zeros to the left that showIntAtBase omitted
|
|
leftPad :: String -> String
|
|
leftPad a = replicate (6 - length a) '0' ++ a
|
|
|
|
--turns list of '0' and '1' into list of 0 and 1
|
|
readBin :: String -> Int
|
|
readBin = fromJust . fmap fst . listToMaybe . readInt 2 (`elem` "01") digitToInt
|
|
|
|
--lookup list for the sextets
|
|
table :: Map.Map Char Int
|
|
table =
|
|
Map.fromList $
|
|
zip "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" [0 ..]
|
|
|
|
main :: IO ()
|
|
main =
|
|
putStrLn $
|
|
byteToASCII
|
|
"VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCi0tIFBhdWwgUi4gRWhybGljaA=="
|