Skip to content

Instantly share code, notes, and snippets.

@viglioni
Last active July 2, 2022 21:54
Show Gist options
  • Save viglioni/ab9e7c974718756985d028bf978b1640 to your computer and use it in GitHub Desktop.
Save viglioni/ab9e7c974718756985d028bf978b1640 to your computer and use it in GitHub Desktop.
Encode/Decode strings into strings of binaries
--
-- Encodes/Decodes string in a string of binaries
--
-- Each char is converted to a string with eight 0s or 1s
-- λ> encode "The darkside of the force is a pathway to many abilities some consider to be unnatural"
-- "0101010001101000011001010010000001100100011000010111001001101011011100110110100101100100011001010
-- 01000000110111101100110001000000111010001101000011001010010000001100110011011110111001001100011011
-- 00101001000000110100101110011001000000110000100100000011100000110000101110100011010000111011101100
-- 00101111001001000000111010001101111001000000110110101100001011011100111100100100000011000010110001
-- 00110100101101100011010010111010001101001011001010111001100100000011100110110111101101101011001010
-- 01000000110001101101111011011100111001101101001011001000110010101110010001000000111010001101111001
-- 00000011000100110010100100000011101010110111001101110011000010111010001110101011100100110000101101
-- 100"
-- λ> decode $ encode "The darkside of the force is a pathway to many abilities some consider to be unnatural"
-- "The darkside of the force is a pathway to many abilities some consider to be unnatural"
import Data.Char (chr, intToDigit, ord)
import Data.List.Split (chunksOf)
import Numeric (showIntAtBase)
-- alias type to differentiate a normal string from a string of 0 and 1's
type BinString = String
-- api
encode :: String -> BinString
encode = concatMap (fillWithZeroes . showInBin . ord)
decode :: BinString -> String
decode = map binToChar . chunksOf 8
binStrToInt :: BinString -> [Int]
binStrToInt = map readToInt
-- private functions
binToChar :: BinString -> Char
binToChar =
chr .
sum . zipWith (\idx bin -> bin * (2 ^ idx)) [0 ..] . reverse . map readToInt
showInBin :: (Integral a, Show a) => a -> String
showInBin n = showIntAtBase 2 intToDigit n ""
fillWithZeroes :: String -> BinString
fillWithZeroes str =
if length str == 8
then str
else fillWithZeroes ('0' : str)
readToInt :: Char -> Int
readToInt = read . pure
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment