based/src/Encoding/Base2.hs

79 lines
2.4 KiB
Haskell

-- module Encoding.Base2
-- ( enc2
-- , dec2
-- ) where
-- import Data.Char (ord, chr, digitToInt, intToDigit)
-- binaryToChar :: String -> Char
-- binaryToChar binStr = chr $ binaryToInt binStr
-- binaryToInt :: String -> Int
-- binaryToInt binStr = Prelude.foldl (\acc x -> acc * 2 + digitToInt x) 0 binStr
-- dec2 :: String -> String
-- dec2 input = map binaryToChar $ words input
-- charToBinary :: Char -> String
-- charToBinary char = let binaryStr = intToBinary $ ord char
-- in replicate (7 - Prelude.length binaryStr) '0' ++ binaryStr
-- intToBinary :: Int -> String
-- intToBinary n = reverse $ decimalToBinary' n
-- where
-- decimalToBinary' 0 = "0"
-- decimalToBinary' m = let (q, r) = m `divMod` 2 in intToDigit r : decimalToBinary' q
-- enc2 :: String -> String
-- enc2 input = unwords $ map charToBinary input
module Encoding.Base2
( enc2
, dec2
, binaryToChar
) where
import Data.Char (ord, chr, digitToInt, intToDigit)
import qualified Data.ByteString.Char8 as BC
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Bits ((.&.), shiftR)
import Data.List (unfoldr)
binaryToChar :: ByteString -> Char
binaryToChar binStr = chr $ binaryToInt (BC.unpack binStr)
binaryToInt :: String -> Int
binaryToInt binStr = foldl (\acc x -> acc * 2 + digitToInt x) 0 binStr
dec2 :: ByteString -> ByteString
dec2 input = BC.pack . map binaryToChar . BC.words $ input
-- charToBinary :: Char -> ByteString
-- charToBinary char = BC.pack $ replicate (7 - length binaryStr) '0' ++ binaryStr
-- where
-- binaryStr = intToBinary (ord char)
charToBinary :: Char -> ByteString
charToBinary char = BC.pack $ replicate (8 - length binaryStr) '0' ++ binaryStr
where
codePoint = ord char
binaryStr = padToLength 8 (intToBinary' codePoint)
padToLength :: Int -> String -> String
padToLength len str
| length str >= len = take len str
| otherwise = replicate (len - length str) '0' ++ str
intToBinary :: Int -> String
intToBinary n = reverse $ decimalToBinary' n
where
decimalToBinary' 0 = "0"
decimalToBinary' m = let (q, r) = m `divMod` 2 in intToDigit r : decimalToBinary' q
intToBinary' :: Int -> String
intToBinary' n = reverse $ take 8 $ unfoldr (\x -> if x == 0 then Nothing else Just (intToDigit $ x .&. 1, x `shiftR` 1)) n
enc2 :: ByteString -> ByteString
enc2 input = BC.unwords . map charToBinary . BC.unpack $ input