diff --git a/.Main.hs.swp b/.Main.hs.swp deleted file mode 100644 index 21d2f52..0000000 Binary files a/.Main.hs.swp and /dev/null differ diff --git a/Main.hs b/app/Main.hs similarity index 66% rename from Main.hs rename to app/Main.hs index 9d552c9..8dfcf06 100644 --- a/Main.hs +++ b/app/Main.hs @@ -49,6 +49,12 @@ import qualified Data.ByteString.Char8 as C import Text.Regex.TDFA import Data.Word (Word8) import Data.Char (ord, chr, intToDigit, digitToInt) +import Encoding.Base2 (enc2, dec2) +import Encoding.Base8 (enc8, dec8) +import Encoding.Base10 (enc10, dec10) +import Encoding.Base16 (enc16, dec16) +import Encoding.Base64 (enc64, dec64, enc64url, dec64url) +import Encoding.Base91 (enc91, dec91) data Based = Decode { b91 :: Bool, @@ -103,22 +109,6 @@ data Based = Decode { -- decoded | C.null decoded -> Left "Failed to decode from base91" -- | otherwise -> Right decoded - -encodeToBase64 :: C.ByteString -> Either String C.ByteString -encodeToBase64 bs = - case B64.encode bs of - encoded | C.null encoded -> Left "Failed to encode Base64.\n" - | otherwise -> Right encoded - -decodeFromBase64 :: C.ByteString -> Either String C.ByteString -decodeFromBase64 bs = - case B64L.decodeLenient bs of - decoded | C.null decoded -> Left "Failed to decode from Base64.\n" - | otherwise -> Right decoded - -- | otherwise -> Right (BSU.toString decoded) - -- Left err -> Left $ "Failed to decode from base64: " ++ err - -- Right decoded -> Right decoded - binToInt :: [Int] -> Int binToInt [] = 0 binToInt (x : xs) = x + 2 * binToInt xs @@ -130,33 +120,6 @@ octToInt (x : xs) = x + 8 * octToInt xs -- base functions -- without the show func, sequences like \n will not be shown as characters but will be executed as newline -dec91 :: String -> String -dec91 = T.unpack . T.decodeUtf8 . B91.decode - --- dec91 input = --- maybe "Error decoding Base91.\n" T.unpack (T.decodeUtf8 (B91.decode input) - --- dec91 :: String -> String --- dec91 input = --- case B91.decode input :: BSU.ByteString of --- decoded -> C.unpack decoded - --- toWord8 :: String -> [Word8] --- toWord8 = map (fromIntegral . fromEnum) - --- dec91 :: String -> String --- dec91 input = --- map (chr . fromIntegral) (B91.decode input :: [Word8]) - --- or - -- case B91.decode input :: [Word8] of - -- Right decoded -> map (toEnum . fromIntegral) decoded - -- Left err -> "Error decoding Base91: " ++ err - - -enc91 :: String -> String -enc91 = B91.encode . BSU.fromString - -- dec85 = C.unpack . U.fromRight . B85.decode . BSU.fromString dec85 :: String -> String dec85 input = @@ -167,29 +130,6 @@ dec85 input = enc85 :: String -> String enc85 = C.unpack . B85.encode . BSU.fromString --- dec64 = C.unpack . B64L.decodeLenient . BSU.fromString -dec64 :: String -> String -dec64 input = - case decodeFromBase64 (BSU.fromString input) of - Right byteString -> C.unpack byteString - Left errMsg -> "Error: " ++ errMsg - --- enc64 = C.unpack . B64.encode . BSU.fromString -enc64 :: String -> String -enc64 input = - case encodeToBase64 (BSU.fromString input) of - Right byteString -> C.unpack byteString - Left errMsg -> "Error: " ++ errMsg - -dec64url :: String -> String --- dec64url = C.unpack . U.fromRight . B64U.decode . BSU.fromString -dec64url input = - case B64.decode (BSU.fromString input) of - Right decoded -> C.unpack decoded - Left _ -> "Error decoding Base64 for URLs.\n" - -enc64url :: String -> String -enc64url = C.unpack . B64U.encode . BSU.fromString decurl :: String -> String decurl = HB.urlDecode @@ -252,145 +192,6 @@ dec32 input = enc32 :: String -> String enc32 = C.unpack . B32.encode . BSU.fromString -dec16 :: String -> String --- dec16 = C.unpack . U.fromRight . B16.decode . BSU.fromString -dec16 input = - case B16.decode (BSU.fromString input) of - Right decoded -> C.unpack decoded - Left _ -> "Error decoding Base16.\n" - -enc16 :: String -> String -enc16 = C.unpack . B16.encode . BSU.fromString - -dec10 :: String -> String -dec10 = show . hexStringToInt - -enc10 :: String -> String --- enc10 = C.unpack . BSU.fromString . intToHexString . decimalStringToInt -- Depending on what you want, do enc10 = show . map ord -enc10 str = C.unpack $ C.pack $ Prelude.foldl (\acc char -> acc ++ show (ord char)) "" str - --- decode octal --- octalToChar :: String -> Char --- octalToChar str = chr $ Prelude.foldl (\acc c -> acc * 8 + read [c]) 0 str - --- Function to decode a single octal value to its corresponding character -octalToChar :: String -> Char -octalToChar octal = chr (read ("0o" ++ octal)) -- Assumes input is in base 8 (octal) - --- Function to split a string into chunks of three characters each -chunksOf3 :: String -> [String] -chunksOf3 [] = [] -chunksOf3 str = Prelude.take 3 str : chunksOf3 (Prelude.drop 3 str) - - --- decodeOctal :: String -> String --- decodeOctal = map (octalToChar . padOctal) . words - -- where - -- -- Function to pad an octal number string with leading '0's if needed - -- padOctal str - -- | Prelude.length str == 1 && str /= "0" = "00" ++ str - -- | Prelude.length str == 2 && str /= "0" = "0" ++ str - -- | otherwise = str - --- Function to decode a string of octal numbers to characters -dec8 :: String -> String -dec8 = map octalToChar . words - --- dec8 :: String -> String --- dec8 = C.unpack . encodeUtf8 . toText . showbOct . hexStringToInt - --- newtype Octal = Octal Int --- octalToString :: Octal -> String --- octalToString (Octal n) = show n - --- dec8 = map (chr . octalToDecimal) . chunksOf 3 --- where --- octalToDecimal :: Octal -> Int --- octalToDecimal (Octal n) = Prelude.foldl (\acc c -> acc * 8 + digitToInt c) O (show n) - --- chunksOf :: Int -> [a] -> [[a]] --- chunksOf _ [] = [] --- chunksOf n xs = Prelude.take n xs : chunksOf n (Prelude.drop n xs) - --- enc8 :: String -> String --- enc8 = C.unpack . BSU.fromString . intToHexString . octToInt . (reverse . (map fromJust . (map fromOctDigit))) --- - - --- unicodeToOctal :: Char -> String --- unicodeToOctal c --- | ord c >= 0 && ord c <= 7 = ['0', intToDigit (ord c)] --- | otherwise = padTo3Bits $ decimalToOctal' (ord c) --- where --- decimalToOctal' 0 = "" --- decimalToOctal' m = let (q, r) = m `divMod` 8 in intToDigit r : decimalToOctal' q - --- padTo3Bits :: String -> String --- padTo3Bits bits --- | Prelude.length bits < 3 = replicate (3 - Prelude.length bits) '0' ++ bits --- | otherwise = bits - --- enc8 :: String -> String --- enc8 = unwords . map (concatMap unicodeToOctal . (:[])) - -chunksOf :: Int -> [a] -> [[a]] -chunksOf _ [] = [] -chunksOf n xs = Prelude.take n xs : chunksOf n (Prelude.drop n xs) - - -unicodeToOctal :: Char -> [String] -unicodeToOctal c = chunksOf 3 $ reverse $ decimalToOctal' (ord c) - where - decimalToOctal' 0 = "0" - decimalToOctal' m = let (q, r) = m `divMod` 8 in intToDigit r : if q == 0 then "" else decimalToOctal' q - -enc8 :: String -> String -enc8 = unwords . concatMap unicodeToOctal - --- unicodeToOctal :: Char -> String --- unicodeToOctal c = reverse $ padTo3Bits $ decimalToOctal' (ord c) --- where --- decimalToOctal' 0 = "0" --- decimalToOctal' m = let (q, r) = m `divMod` 8 in intToDigit r : decimalToOctal' q - --- padTo3Bits :: String -> String --- padTo3Bits bits = replicate (3 - Prelude.length bits) '0' ++ bits - --- enc8 :: String -> String --- enc8 = concatMap unicodeToOctal - --- dec2 :: String -> String --- dec2 = C.unpack . encodeUtf8 . toText . showbBin . hexStringToInt --- dec2 = TL.unpack . toLazyText . showbBin . hexStringToInt . enc16 --- dec2 = TL.unpack . toLazyText . showbBin . hexStringToInt --- -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 - - --- enc2 = C.unpack . BSU.fromString . intToHexString . binToInt . (reverse . (map fromJust . (map fromBinDigit))) --- enc2 input = C.unpack $ C.pack $ show $ Prelude.foldl (\acc char -> (acc `shiftL` 8) .|. fromIntegral (ord char)) BSU.fromString -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 :: String -> String -enc2 input = unwords $ map charToBinary input - - decqp :: String -> String -- decqp = C.unpack . U.fromRight . QP.decode . BSU.fromString decqp input = diff --git a/based.cabal b/based.cabal index a9ec947..d99cdea 100644 --- a/based.cabal +++ b/based.cabal @@ -6,24 +6,39 @@ extra-source-files: CHANGELOG.md author: Stefan Friese library + hs-source-dirs: src exposed-modules: - MyLib + Encoding.Base2 + Encoding.Base8 + Encoding.Base10 + Encoding.Base16 + Encoding.Base64 + Encoding.Base91 other-modules: -- Data.Bytes.Text.Ascii build-depends: -- base ^>= 4.13.0.0, base, -- byteslice == 0.2.6.0, + sandi, + base91, + utf8-string, byteslice, + bytestring, + hxt, + text, + base64-bytestring -- hs-source-dirs: default-language: Haskell2010 executable based + hs-source-dirs: app main-is: Main.hs - other-modules: MyLib + -- other-modules: MyLib build-depends: -- base ^>= 4.13.0.0, base, + based, cmdargs, sandi, base62, diff --git a/src/Encoding/Base10.hs b/src/Encoding/Base10.hs new file mode 100644 index 0000000..705b525 --- /dev/null +++ b/src/Encoding/Base10.hs @@ -0,0 +1,14 @@ +module Encoding.Base10 + ( enc10 + , dec10 + ) where + +import qualified Data.ByteString.Char8 as C +import Data.Char (ord, chr, digitToInt, intToDigit) +import Text.XML.HXT.DOM.Util (hexStringToInt) + +dec10 :: String -> String +dec10 = show . hexStringToInt + +enc10 :: String -> String +enc10 str = C.unpack $ C.pack $ Prelude.foldl (\acc char -> acc ++ show (ord char)) "" str diff --git a/src/Encoding/Base16.hs b/src/Encoding/Base16.hs new file mode 100644 index 0000000..29935e9 --- /dev/null +++ b/src/Encoding/Base16.hs @@ -0,0 +1,17 @@ +module Encoding.Base16 + ( enc16 + , dec16 + ) where + +import qualified Data.ByteString.Char8 as C +import Data.ByteString.UTF8 as BSU +import qualified Codec.Binary.Base16 as B16 + +dec16 :: String -> String +dec16 input = + case B16.decode (BSU.fromString input) of + Right decoded -> C.unpack decoded + Left _ -> "Error decoding Base16.\n" + +enc16 :: String -> String +enc16 = C.unpack . B16.encode . BSU.fromString diff --git a/src/Encoding/Base2.hs b/src/Encoding/Base2.hs new file mode 100644 index 0000000..bb6842c --- /dev/null +++ b/src/Encoding/Base2.hs @@ -0,0 +1,30 @@ +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 + diff --git a/src/Encoding/Base64.hs b/src/Encoding/Base64.hs new file mode 100644 index 0000000..1378cd9 --- /dev/null +++ b/src/Encoding/Base64.hs @@ -0,0 +1,49 @@ +module Encoding.Base64 + ( enc64 + , dec64 + , enc64url + , dec64url + ) where + + +import Data.ByteString.UTF8 as BSU -- from utf8-string +import qualified Data.ByteString.Char8 as C +import qualified Codec.Binary.Base64 as B64 +import qualified Data.ByteString.Base64 as B64L +import qualified Codec.Binary.Base64Url as B64U + +encodeToBase64 :: C.ByteString -> Either String C.ByteString +encodeToBase64 bs = + case B64.encode bs of + encoded | C.null encoded -> Left "Failed to encode Base64.\n" + | otherwise -> Right encoded + +decodeFromBase64 :: C.ByteString -> Either String C.ByteString +decodeFromBase64 bs = + case B64L.decodeLenient bs of + decoded | C.null decoded -> Left "Failed to decode from Base64.\n" + | otherwise -> Right decoded + -- | otherwise -> Right (BSU.toString decoded) + -- Left err -> Left $ "Failed to decode from base64: " ++ err + -- Right decoded -> Right decoded + +dec64 :: String -> String +dec64 input = + case decodeFromBase64 (BSU.fromString input) of + Right byteString -> C.unpack byteString + Left errMsg -> "Error: " ++ errMsg + +enc64 :: String -> String +enc64 input = + case encodeToBase64 (BSU.fromString input) of + Right byteString -> C.unpack byteString + Left errMsg -> "Error: " ++ errMsg + +dec64url :: String -> String +dec64url input = + case B64.decode (BSU.fromString input) of + Right decoded -> C.unpack decoded + Left _ -> "Error decoding Base64 for URLs.\n" + +enc64url :: String -> String +enc64url = C.unpack . B64U.encode . BSU.fromString diff --git a/src/Encoding/Base8.hs b/src/Encoding/Base8.hs new file mode 100644 index 0000000..2964e9a --- /dev/null +++ b/src/Encoding/Base8.hs @@ -0,0 +1,30 @@ +module Encoding.Base8 + ( enc8 + , dec8 + ) where + +import Data.Char (ord, chr, intToDigit) + +octalToChar :: String -> Char +octalToChar octal = chr (read ("0o" ++ octal)) -- Assumes input is in base 8 (octal) + +-- Function to split a string into chunks of three characters each +chunksOf3 :: String -> [String] +chunksOf3 [] = [] +chunksOf3 str = Prelude.take 3 str : chunksOf3 (Prelude.drop 3 str) + +dec8 :: String -> String +dec8 = map octalToChar . words + +chunksOf :: Int -> [a] -> [[a]] +chunksOf _ [] = [] +chunksOf n xs = Prelude.take n xs : chunksOf n (Prelude.drop n xs) + +unicodeToOctal :: Char -> [String] +unicodeToOctal c = chunksOf 3 $ reverse $ decimalToOctal' (ord c) + where + decimalToOctal' 0 = "0" + decimalToOctal' m = let (q, r) = m `divMod` 8 in intToDigit r : if q == 0 then "" else decimalToOctal' q + +enc8 :: String -> String +enc8 = unwords . concatMap unicodeToOctal diff --git a/src/Encoding/Base91.hs b/src/Encoding/Base91.hs new file mode 100644 index 0000000..a9a1cfb --- /dev/null +++ b/src/Encoding/Base91.hs @@ -0,0 +1,17 @@ +module Encoding.Base91 + ( enc91 + , dec91 + ) where + +import qualified Data.ByteString.Char8 as C +import Data.ByteString.UTF8 as BSU +import qualified Codec.Binary.Base91 as B91 +import qualified Data.Text as T +-- import qualified Data.Text.IO as T +import qualified Data.Text.Encoding as T + +dec91 :: String -> String +dec91 = T.unpack . T.decodeUtf8 . B91.decode + +enc91 :: String -> String +enc91 = B91.encode . BSU.fromString