summaryrefslogtreecommitdiff
path: root/base64/base64.hs
diff options
context:
space:
mode:
Diffstat (limited to 'base64/base64.hs')
-rw-r--r--base64/base64.hs45
1 files changed, 45 insertions, 0 deletions
diff --git a/base64/base64.hs b/base64/base64.hs
new file mode 100644
index 0000000..13f12bb
--- /dev/null
+++ b/base64/base64.hs
@@ -0,0 +1,45 @@
+--
+-- Miguel's Naive
+-- Base64 Encoder -- Coded on a winter afterfnoon on 19th Feb 2018 A.D.
+-- to fully understand base64 encoding and play with
+-- haskell, which is always an indisputable pleasure.
+--
+-- The following lines were written in full awareness
+-- that 'libraries' for this purpose, which perform way
+-- better, are in existence.
+--
+-- Coded in big anger due to nick's stories about saving his binary
+-- format, encrypted passwords in an ascii config file, featuring
+-- strange letters and characters.
+--
+-- Example Usage: echo "just testing" | stack runghc base64.hs | stack runghc base64 -- -d
+-- (You can cross check with base64 / base64 -d)
+
+import System.Environment
+import qualified Data.List.Split as T
+import qualified Data.List as L
+import qualified Data.Map.Strict as M
+import qualified Data.ByteString.Lazy as B
+import Text.Printf
+import Data.Maybe
+import Data.Char
+import Control.Monad
+
+main = do args<-getArgs
+ if length args == 0 then go encode64
+ else when (args!!0 == "-d") $ go decode64
+ where go f = getContents >>= putStr.(++"\n").f
+
+fromBase64 x = (['A'..'Z']++['a'..'z']++['0'..'9']++['+','/']) !! x
+mapBase64 = M.fromList $ map (\x-> (fromBase64 x,x)) [0..63]
+binToDec = sum . map (2^) . L.findIndices (=='1') . reverse
+
+encode64 x = pad64 (length x) . map (fromBase64 . binToDec) . T.chunksOf 6 .
+ concat . map (printf "%08b" ) $ x ++ cycle "\000"
+
+decode64 x = map (chr . binToDec) . T.chunksOf 8 .
+ concat . map ( printf "%06b" . fromJust) . filter isJust .
+ map (flip M.lookup mapBase64) $ x
+
+pad64 l = (++(take m ((cycle "=")))) . take ((l+m)*3 `div` 2 -3-m)
+ where m = mod (3 - mod l 3) 3