Compare commits

...

32 Commits

Author SHA1 Message Date
Stefan Friese 85b57ef9aa added unary encoding 2024-11-19 18:24:36 +01:00
Stefan Friese e39ac84573 added changelog 2024-09-25 23:59:41 +02:00
Stefan Friese 3bc2062bf3 incremented to minor version 0.4.5 2024-09-25 23:36:19 +02:00
Stefan Friese 6213a4a221 added tap code 2024-07-02 23:03:58 +02:00
Stefan Friese f06925d9b8 added tap code 2024-07-02 23:02:51 +02:00
Stefan Friese b60acf2008 added bindings for morse code, bug fix 2024-06-27 23:16:56 +02:00
Stefan Friese 3bd5530544 added morse encoding, WIP 2024-06-26 23:56:59 +02:00
Stefan Friese f5d35aa555 simplified functions, ignore non ascii characters 2024-06-24 23:23:10 +02:00
Stefan Friese e0d97a4084 added letter to number encoding, WIP. Non Ascii character throw an error right, now. Maybe gonna change it so bytestring is output unchanged 2024-06-23 19:30:10 +02:00
Stefan Friese 8664170b0d fixed some bugs with solve function 2024-06-11 15:40:59 +02:00
Stefan Friese 61313cd558 moved solve function from Main.hs to src/Encoding/Solve.hs 2024-06-11 15:21:23 +02:00
Stefan Friese 63a0fd3c05 added test for rotate function and yencode/decode 2024-06-11 14:48:57 +02:00
Stefan Friese 5e4a146b4f updated Changelog and README, release of v.0.4.4 2024-06-10 22:09:18 +02:00
Stefan Friese c3bedaee2f fixed a bug in url encoding, complete test coverage for all encodings now 2024-06-10 20:54:23 +02:00
Stefan Friese 28b583d6b8 reintroduced solve function 2024-06-09 22:48:37 +02:00
Stefan Friese a5f9862df1 added correct description to arguments of encode and decode functions 2024-06-09 22:27:28 +02:00
Stefan Friese 736627ff3d added tests for base10 2024-06-09 22:14:50 +02:00
Stefan Friese 37985bd205 refractored Uu encoding, so it is more correct, added tests for Uu encode 2024-06-09 20:56:00 +02:00
Stefan Friese 6ab4cbaa79 moved all encodings to bytestring in- and output 2024-06-09 15:32:39 +02:00
Stefan Friese 82aed9340c moved all encodings to bytestring, updated tests accordingly 2024-06-09 13:12:23 +02:00
Stefan Friese 1889691259 rewrote test so bytestrings are tested 2024-06-08 23:55:11 +02:00
Stefan Friese b6ad312970 Changed base45 to Bytestring in and output 2024-06-08 22:04:28 +02:00
Stefan Friese a472d309a6 changed octal encoding to bytestring instead of string 2024-06-08 21:38:01 +02:00
Stefan Friese b91f110f42 changed rotate to match ByteStrings instead of Strings 2024-06-08 20:26:16 +02:00
Stefan Friese fbb10d0edf Regression atm, Moved from Unicode/Utf8 to ByteString so binary data is encoded correctly. WIP 2024-06-07 18:09:20 +02:00
Stefan Friese faf12b64f1 moved Uu encoding to Text instead of string 2024-06-06 18:18:48 +02:00
Stefan Friese 550f40ce4a added test for quoted printable encoding and decoding 2024-06-06 13:13:14 +02:00
Stefan Friese 15abc2c95b added tests for base91 and base85 2024-06-04 21:59:23 +02:00
Stefan Friese 580792ddf6 added base45 tests 2024-06-04 17:09:18 +02:00
Stefan Friese 87089a314b added base45 encoding/decoding 2024-05-23 22:32:15 +02:00
Stefan Friese 5d1bd6abc2 added tests section 2024-05-22 22:36:17 +02:00
Stefan Friese d622618a41 updated README 2024-05-22 22:33:27 +02:00
27 changed files with 1272 additions and 382 deletions

View File

@ -1,5 +1,19 @@
Revision history for based Revision history for based
0.4.5.0 -- 2024-09-25
Added tap code
Removed some bugs of the solve functions
Added bindings for morse code, bug fix
Simplified functions, ignore non ascii characters
Added test for rotate function and yencode/decode
0.4.4.0 -- 2024-06-09
Added tests for every encode function included
Moved from String to ByteString for input and output, so binary data is encoded and decoded correctly
Fixed several issues with incorrect encodings
0.4.3.0 -- 2024-05-22 0.4.3.0 -- 2024-05-22
Added rotate function to encode and decode Added rotate function to encode and decode

View File

@ -1,6 +1,7 @@
# based # based
A commandline tool that lets you encode and decode most of the bases. A commandline binary-to-text encoder which has most
common bases included.
Release binary is statically linked and stripped via Release binary is statically linked and stripped via
```sh ```sh
@ -8,9 +9,13 @@ cabal v2-build --enable-executable-static -O2
strip --strip-all based strip --strip-all based
``` ```
Do not forget to set `$LD_LIBRARY_PATH` to the directory of your static libs,
e.g. `export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu`.
## Compilation ## Compilation
* If you want to compile your own build, link it dynamically via * If you want to compile your own build, link it dynamically via
```sh ```sh
git clone https://git.stefan.works/whx/based.git git clone https://git.stefan.works/whx/based.git
cd based/ cd based/
@ -18,6 +23,11 @@ cabal install
cabal run cabal run
``` ```
## Download Binary
If you want to download the statically linked binary, fetch the latest release
from https://git.stefan.works/whx/based/releases .
## Usage ## Usage
* Pipe via stdin to transcode * Pipe via stdin to transcode
@ -33,23 +43,29 @@ echo '>OwJh>}AQ;r@@Y?FF' | based --b91
Hello, World! Hello, World!
``` ```
### Tests
Run `cabal test`
## What is Transcoded? ## What is Transcoded?
The following are the supported encodings The following are the supported encodings
* Base91 * Base91
* Base85 * Base85
* Base64 * Base64
* Base64url * Base64url
* URI Encoding * URL Encoding
* Base62 * Base62
* Base58 * Base58
* Base45
* Base32 * Base32
* Base16
* Base10
* Base2
* Quoted-Printable * Quoted-Printable
* UU Encoding * UU Encoding
* XX Encoding * XX Encoding
* yEncoding * yEncoding
* Char to Hex and vice versa * Rotate (1..26)
* Decimal to Hex and vice versa
* Oktal to Hex and vice versa
* Binary to Hex and vice versa

View File

@ -1,18 +1,16 @@
#!/usr/bin/env runhaskell #!/usr/bin/env runhaskell
{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveDataTypeable #-}
module Main where module Main where
import System.Console.CmdArgs import System.Console.CmdArgs
import Control.Arrow import qualified Data.ByteString as B
import Data.ByteString.UTF8 as BSU -- from utf8-string
import qualified Data.ByteString.Char8 as C
import Text.Regex.TDFA
import Encoding.Base2 (enc2, dec2) import Encoding.Base2 (enc2, dec2)
import Encoding.Base8 (enc8, dec8) import Encoding.Base8 (enc8, dec8)
import Encoding.Base10 (enc10, dec10) import Encoding.Base10 (enc10, dec10)
import Encoding.Base16 (enc16, dec16) import Encoding.Base16 (enc16, dec16)
import Encoding.Base32 (enc32, dec32) import Encoding.Base32 (enc32, dec32)
import Encoding.Base45 (enc45, dec45)
import Encoding.Base58 (enc58, dec58) import Encoding.Base58 (enc58, dec58)
import Encoding.Base62 (enc62, dec62) import Encoding.Base62 (enc62, dec62)
import Encoding.Base64 (enc64, dec64, enc64url, dec64url) import Encoding.Base64 (enc64, dec64, enc64url, dec64url)
@ -23,7 +21,11 @@ import Encoding.Xx (encxx, decxx)
import Encoding.QuotedPrintable (encqp, decqp) import Encoding.QuotedPrintable (encqp, decqp)
import Encoding.UnixToUnix (encuu, decuu) import Encoding.UnixToUnix (encuu, decuu)
import Encoding.Yenc (ency, decy) import Encoding.Yenc (ency, decy)
import Encoding.LetterToNumber (encltn, decltn)
import Encoding.Rotate (rotate) import Encoding.Rotate (rotate)
import Encoding.Morse (encmorse, decmorse)
import Encoding.Tap (enctap, dectap)
import Encoding.Solve (solveEnc)
data Based = Decode { data Based = Decode {
@ -34,6 +36,7 @@ data Based = Decode {
url :: Bool, url :: Bool,
b62 :: Bool, b62 :: Bool,
b58 :: Bool, b58 :: Bool,
b45 :: Bool,
b32 :: Bool, b32 :: Bool,
b16 :: Bool, b16 :: Bool,
b10 :: Bool, b10 :: Bool,
@ -43,7 +46,10 @@ data Based = Decode {
uu :: Bool, uu :: Bool,
xx :: Bool, xx :: Bool,
yenc :: Bool, yenc :: Bool,
a1z26 :: Bool,
rot :: Maybe Int, rot :: Maybe Int,
morse :: Bool,
tap :: Bool,
solve :: Bool solve :: Bool
} }
| Encode { | Encode {
@ -54,6 +60,7 @@ data Based = Decode {
url :: Bool, url :: Bool,
b62 :: Bool, b62 :: Bool,
b58 :: Bool, b58 :: Bool,
b45 :: Bool,
b32 :: Bool, b32 :: Bool,
b16 :: Bool, b16 :: Bool,
b10 :: Bool, b10 :: Bool,
@ -63,89 +70,15 @@ data Based = Decode {
uu :: Bool, uu :: Bool,
xx :: Bool, xx :: Bool,
yenc :: Bool, yenc :: Bool,
a1z26 :: Bool,
morse :: Bool,
tap :: Bool,
rot :: Maybe Int rot :: Maybe Int
} }
deriving(Show, Data, Typeable) deriving(Show, Data, Typeable)
-- helper functions
-- convertToByteString :: String -> Either String C.ByteString optionHandler :: Based -> B.ByteString -> B.ByteString
-- convertToByteString str =
-- case BSU.fromString str of
-- Just bs -> Right bs
-- Nothing -> Left "Failed to convert string to ByteString."
-- decodeFromBase91 :: String -> Either String C.ByteString
-- decodeFromBase91 decoded =
-- case B91.decode of
-- decoded | C.null decoded -> Left "Failed to decode from base91"
-- | otherwise -> Right decoded
binToInt :: [Int] -> Int
binToInt [] = 0
binToInt (x : xs) = x + 2 * binToInt xs
octToInt :: [Int] -> Int
octToInt [] = 0
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
base91Regex = "^[!-~]*$"
base85Regex = "^[0-9A-Za-z!#$%&()*+,-;<=>?@^_`{|}~]+$"
-- base85Regex = "^[A-Za-u0-9!\"#$%&((*+,-./;:<=@[]\\`]*$"
base64Regex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$"
base58Regex = "^[1-9A-HJ-NP-Za-km-z]+$" -- incorrect
base32Regex = "^(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=)?$"
base16Regex = "^[0-9A-FXx]*$"
base10Regex = "^[0-9]*$"
base8Regex = "^[0-7]*$"
base2Regex = "^[01]*$"
urlRegex = "^[a-zA-Z0-9%]*$"
solveEnc :: String -> String
solveEnc input =
let isBase91 = BSU.fromString input =~ base91Regex :: Bool
isBase85 = BSU.fromString input =~ base85Regex :: Bool
isBase64 = BSU.fromString input =~ base64Regex :: Bool
isBase58 = BSU.fromString input =~ base58Regex :: Bool
isBase32 = BSU.fromString input =~ base32Regex :: Bool
isBase16 = BSU.fromString input =~ base16Regex :: Bool
isBase10 = BSU.fromString input =~ base10Regex :: Bool
isBase8 = BSU.fromString input =~ base8Regex :: Bool
isBase2 = BSU.fromString input =~ base2Regex :: Bool
isURL = BSU.fromString input =~ urlRegex :: Bool
base91Result = if isBase91 then "\nTrying base91:\n" ++ dec91 input else ""
base85Result = if isBase85 then "\nTrying base85:\n" ++ dec85 input else ""
base64Result = if isBase64 then "\nTrying base64:\n" ++ dec64 input else ""
base58Result = if isBase58 then "\nTrying base58:\n" ++ dec58 input else ""
base32Result = if isBase64 then "\nTrying base32:\n" ++ dec32 input else ""
base16Result = if isBase16 then "\nTrying base16:\n" ++ dec16 input else ""
base10Result = if isBase10 then "\nTrying base10:\n" ++ dec10 input else ""
base2Result = if isBase2 then "\nTrying base2:\n" ++ dec2 input else ""
base8Result = if isBase8 then "\nTrying base8:\n" ++ dec8 input else ""
urlResult = if isURL then "\nTrying URL decode:\n" ++ decurl input else ""
results = filter (not . null) [base91Result, base85Result, base64Result, base58Result, base32Result, base16Result, base10Result, base8Result, base2Result, urlResult]
in
if null results
then "Not able to solve the encoding.\n"
else unlines results
--
-- | input =~ base64Regex = dec64 input
-- | input =~ base32Regex = dec32 input
-- | otherwise = "Cannot decode: " ++ input
--
-- if BSU.fromString input =~ base64Regex :: Bool
-- then dec64 input
-- else "Not Base64.\n"
-- ++ if BSU.fromString input =~ base32Regex :: Bool
-- then dec32 input
-- else "Not able to solve the encoding.\n"
-- optionHandler :: EncodeOptions -> Text -> Text
optionHandler Decode{b91=True} = dec91 optionHandler Decode{b91=True} = dec91
optionHandler Encode{b91=True} = enc91 optionHandler Encode{b91=True} = enc91
optionHandler Decode{b85=True} = dec85 optionHandler Decode{b85=True} = dec85
@ -160,6 +93,8 @@ optionHandler Decode{b62=True} = dec62
optionHandler Encode{b62=True} = enc62 optionHandler Encode{b62=True} = enc62
optionHandler Decode{b58=True} = dec58 optionHandler Decode{b58=True} = dec58
optionHandler Encode{b58=True} = enc58 optionHandler Encode{b58=True} = enc58
optionHandler Decode{b45=True} = dec45
optionHandler Encode{b45=True} = enc45
optionHandler Decode{b32=True} = dec32 optionHandler Decode{b32=True} = dec32
optionHandler Encode{b32=True} = enc32 optionHandler Encode{b32=True} = enc32
optionHandler Decode{b16=True} = dec16 optionHandler Decode{b16=True} = dec16
@ -178,8 +113,14 @@ optionHandler Decode{xx=True} = decxx
optionHandler Encode{xx=True} = encxx optionHandler Encode{xx=True} = encxx
optionHandler Decode{yenc=True} = decy optionHandler Decode{yenc=True} = decy
optionHandler Encode{yenc=True} = ency optionHandler Encode{yenc=True} = ency
optionHandler Encode{rot=Just n} = rotate n optionHandler Decode{a1z26=True} = decltn
optionHandler Encode{a1z26=True} = encltn
optionHandler Decode{rot=Just n} = rotate n optionHandler Decode{rot=Just n} = rotate n
optionHandler Encode{rot=Just n} = rotate n
optionHandler Decode{morse=True} = decmorse
optionHandler Encode{morse=True} = encmorse
optionHandler Decode{tap=True} = dectap
optionHandler Encode{tap=True} = enctap
optionHandler Decode{solve=True} = solveEnc optionHandler Decode{solve=True} = solveEnc
decodeMode :: Based decodeMode :: Based
@ -188,19 +129,23 @@ decodeMode = Decode {
b85 = def &= help "decode base85", b85 = def &= help "decode base85",
b64 = def &= help "decode base64", b64 = def &= help "decode base64",
b64url = def &= help "decode base64Url", b64url = def &= help "decode base64Url",
url = def &= help "decode URI", url = def &= help "decode URL",
b62 = def &= help "decode base62", b62 = def &= help "decode base62",
b58 = def &= help "decode base58", b58 = def &= help "decode base58",
b45 = def &= help "decode base45",
b32 = def &= help "decode base32", b32 = def &= help "decode base32",
b16 = def &= help "decode base16", b16 = def &= help "decode base16",
b10 = def &= help "decode decimal from hex", b10 = def &= help "decode decimal",
b8 = def &= help "decode octal from hex", b8 = def &= help "decode octal",
b2 = def &= help "decode binary from hex", b2 = def &= help "decode base2",
qp = def &= help "decode quoted-printable", qp = def &= help "decode quoted-printable",
uu = def &= help "decode uu", uu = def &= help "decode UnixToUnix",
xx = def &= help "decode xx", xx = def &= help "decode xx, without padding",
yenc = def &= help "decode yEncode", yenc = def &= help "decode yEncode",
a1z26 = def &= help "decode letter to number",
rot = def &= help "rotate characters by n positions", rot = def &= help "rotate characters by n positions",
morse = def &= help "decode morse",
tap = def &= help "decode tap code using a Polybius square (5x5 grid Latin alphabet)",
solve = def &= help "solve encoding" solve = def &= help "solve encoding"
} &= help "Decode chosen base" &=auto } &= help "Decode chosen base" &=auto
@ -210,20 +155,27 @@ encodeMode = Encode {
b85 = def &= help "encode base85", b85 = def &= help "encode base85",
b64 = def &= help "encode base64", b64 = def &= help "encode base64",
b64url = def &= help "encode base64Url", b64url = def &= help "encode base64Url",
url = def &= help "encode URI", url = def &= help "encode URL",
b62 = def &= help "encode base62", b62 = def &= help "encode base62",
b58 = def &= help "encode base58", b58 = def &= help "encode base58",
b45 = def &= help "encode base45",
b32 = def &= help "encode base32", b32 = def &= help "encode base32",
b16 = def &= help "encode base16", b16 = def &= help "encode base16",
b10 = def &= help "encode base10 to hex", b10 = def &= help "encode decimal",
b8 = def &= help "encode octal to hex", b8 = def &= help "encode octal",
b2 = def &= help "encode binary to hex", b2 = def &= help "encode base2",
qp = def &= help "encode quoted-printable", qp = def &= help "encode quoted-printable",
uu = def &= help "encode uu", uu = def &= help "encode UnixToUnix",
xx = def &= help "encode xx", xx = def &= help "encode xx, without padding",
yenc = def &= help "encode yEncode", yenc = def &= help "encode yEncode",
rot = def &= help "rotate characters by n positions" a1z26 = def &= help "encode letter to number",
rot = def &= help "rotate characters by n positions",
morse = def &= help "encode morse",
tap = def &= help "encode tap code using a Polybius square (5x5 grid Latin alphabet)"
} &= help "Encode chosen base" } &= help "Encode chosen base"
main :: IO() main :: IO()
main = cmdArgs (modes[decodeMode, encodeMode] &= help "Based, when Cyberchef doesn't cut it.\nTo see every parameter of every mode use --help=all" &= program "based" &= summary "based v0.4") >>= interact . optionHandler main = do
args <- cmdArgs(modes[decodeMode, encodeMode] &= help "Based, Binary to text encoding.\nTo see arguments of encode and decode modes use --help=all" &= program "based" &= summary "based v0.4")
input <- B.getContents
B.putStr $ optionHandler args input

View File

@ -1,6 +1,6 @@
cabal-version: 2.4 cabal-version: 2.4
name: based name: based
version: 0.4.2.0 version: 0.4.5.0
license-file: LICENSE license-file: LICENSE
extra-source-files: CHANGELOG.md extra-source-files: CHANGELOG.md
author: Stefan Friese author: Stefan Friese
@ -13,6 +13,7 @@ library
Encoding.Base10 Encoding.Base10
Encoding.Base16 Encoding.Base16
Encoding.Base32 Encoding.Base32
Encoding.Base45
Encoding.Base58 Encoding.Base58
Encoding.Base62 Encoding.Base62
Encoding.Base64 Encoding.Base64
@ -24,6 +25,10 @@ library
Encoding.Xx Encoding.Xx
Encoding.Yenc Encoding.Yenc
Encoding.Rotate Encoding.Rotate
Encoding.LetterToNumber
Encoding.Morse
Encoding.Tap
Encoding.Solve
other-modules: other-modules:
-- Data.Bytes.Text.Ascii -- Data.Bytes.Text.Ascii
build-depends: build-depends:
@ -40,7 +45,12 @@ library
hxt, hxt,
haskoin-core, haskoin-core,
text, text,
base64-bytestring primitive,
regex-tdfa,
base64-bytestring,
containers,
split,
MorseCode
default-language: Haskell2010 default-language: Haskell2010
executable based executable based
@ -54,6 +64,7 @@ executable based
cmdargs, cmdargs,
utf8-string, utf8-string,
bytestring, bytestring,
-- base64-bytestring,
regex-tdfa regex-tdfa
-- sandi, -- sandi,
-- base62, -- base62,
@ -80,5 +91,7 @@ test-suite based-test
build-depends: build-depends:
base, base,
based, based,
bytestring,
utf8-string,
HUnit HUnit
default-language: Haskell2010 default-language: Haskell2010

View File

@ -3,12 +3,16 @@ module Encoding.Base10
, dec10 , dec10
) where ) where
import qualified Data.ByteString.Char8 as C import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import Data.Char (ord, chr, digitToInt, intToDigit) import Data.Char (ord, chr, digitToInt, intToDigit)
dec10 :: String -> String -- dec10 :: String -> String
dec10 = map (chr . read) . words -- dec10 = map (chr . read) . words
dec10 :: B.ByteString -> B.ByteString
dec10 = BC.pack . Prelude.map (chr . read) . words . BC.unpack
enc10 :: String -> String -- enc10 :: String -> String
enc10 = unwords . map (show . ord) enc10 :: B.ByteString -> B.ByteString
enc10 = BC.pack . unwords . Prelude.map (show . ord) . BC.unpack
-- enc10 str = C.unpack $ C.pack $ Prelude.foldl (\acc char -> acc ++ show (ord char)) "" str -- enc10 str = C.unpack $ C.pack $ Prelude.foldl (\acc char -> acc ++ show (ord char)) "" str

View File

@ -3,18 +3,27 @@ module Encoding.Base16
, dec16 , dec16
) where ) where
import qualified Data.ByteString.Char8 as C
import Data.ByteString.UTF8 as BSU import Data.ByteString.UTF8 as BSU
import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import qualified Codec.Binary.Base16 as B16 import qualified Codec.Binary.Base16 as B16
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
import qualified Data.Text.IO as T import qualified Data.Text.IO as T
dec16 :: String -> String -- dec16 :: String -> String
dec16 input = -- dec16 input =
case B16.decode (BSU.fromString input) of -- case B16.decode (BSU.fromString input) of
Right decoded -> T.unpack (T.decodeUtf8 decoded) -- Right decoded -> T.unpack (T.decodeUtf8 decoded)
Left _ -> "Error decoding Base16.\n" -- Left _ -> "Error decoding Base16.\n"
enc16 :: String -> String dec16 :: B.ByteString -> B.ByteString
enc16 = C.unpack . B16.encode . BSU.fromString dec16 input = case B16.decode input of
Right byteString -> byteString
Left _ -> BC.pack "Error: Invalid Hexadecimal input"
-- enc16 :: String -> String
-- enc16 = C.unpack . B16.encode . BSU.fromString
enc16 :: B.ByteString -> B.ByteString
enc16 = B16.encode

View File

@ -1,23 +1,69 @@
-- 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 module Encoding.Base2
( enc2 ( enc2
, dec2 , dec2
, binaryToChar
) where ) where
import Data.Char (ord, chr, digitToInt, intToDigit) 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 :: String -> Char binaryToChar :: ByteString -> Char
binaryToChar binStr = chr $ binaryToInt binStr binaryToChar binStr = chr $ binaryToInt (BC.unpack binStr)
binaryToInt :: String -> Int binaryToInt :: String -> Int
binaryToInt binStr = Prelude.foldl (\acc x -> acc * 2 + digitToInt x) 0 binStr binaryToInt binStr = foldl (\acc x -> acc * 2 + digitToInt x) 0 binStr
dec2 :: String -> String dec2 :: ByteString -> ByteString
dec2 input = map binaryToChar $ words input 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)
charToBinary :: Char -> String padToLength :: Int -> String -> String
charToBinary char = let binaryStr = intToBinary $ ord char padToLength len str
in replicate (7 - Prelude.length binaryStr) '0' ++ binaryStr | length str >= len = take len str
| otherwise = replicate (len - length str) '0' ++ str
intToBinary :: Int -> String intToBinary :: Int -> String
intToBinary n = reverse $ decimalToBinary' n intToBinary n = reverse $ decimalToBinary' n
@ -25,6 +71,8 @@ intToBinary n = reverse $ decimalToBinary' n
decimalToBinary' 0 = "0" decimalToBinary' 0 = "0"
decimalToBinary' m = let (q, r) = m `divMod` 2 in intToDigit r : decimalToBinary' q decimalToBinary' m = let (q, r) = m `divMod` 2 in intToDigit r : decimalToBinary' q
enc2 :: String -> String intToBinary' :: Int -> String
enc2 input = unwords $ map charToBinary input 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

View File

@ -4,18 +4,27 @@ module Encoding.Base32
) where ) where
import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import Data.ByteString.UTF8 as BSU -- from utf8-string import Data.ByteString.UTF8 as BSU -- from utf8-string
import qualified Data.ByteString.Char8 as C
import qualified Codec.Binary.Base32 as B32 import qualified Codec.Binary.Base32 as B32
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
import qualified Data.Text.IO as T import qualified Data.Text.IO as T
dec32 :: String -> String -- dec32 :: String -> String
dec32 input = -- dec32 input =
case B32.decode (BSU.fromString input) of -- case B32.decode (BSU.fromString input) of
Right decoded -> T.unpack (T.decodeUtf8 decoded) -- Right decoded -> T.unpack (T.decodeUtf8 decoded)
Left _ -> "Error decoding Base32.\n" -- Left _ -> "Error decoding Base32.\n"
enc32 :: String -> String dec32 :: B.ByteString -> B.ByteString
enc32 = C.unpack . B32.encode . BSU.fromString dec32 input = case B32.decode input of
Right byteString -> byteString
Left _ -> BC.pack "Error: Invalid Base32 input"
-- enc32 :: String -> String
-- enc32 = C.unpack . B32.encode . BSU.fromString
enc32 :: B.ByteString -> B.ByteString
enc32 = B32.encode

172
src/Encoding/Base45.hs Normal file
View File

@ -0,0 +1,172 @@
-- module Encoding.Base45
-- ( enc45
-- , dec45
-- ) where
-- import Data.Char (chr, ord)
-- import Data.List (elemIndex)
-- import Data.Maybe (fromJust)
-- base45Alphabet :: String
-- base45Alphabet = ['0'..'9'] ++ ['A'..'Z'] ++ " " ++ "$%*+-./:"
-- enc45 :: String -> String
-- enc45 = concatMap (reverse . encodeChunk) . chunkBy 2 . map ord
-- chunkBy :: Int -> [a] -> [[a]]
-- chunkBy _ [] = []
-- chunkBy n xs = take n xs : chunkBy n (drop n xs)
-- encodeChunk :: [Int] -> String
-- encodeChunk [x1, x2] = map (base45Alphabet !!) [c, b, a]
-- where
-- n = x1 * 256 + x2
-- a = n `mod` 45
-- b = (n `div` 45) `mod` 45
-- c = n `div` 2025
-- encodeChunk [x1] = map (base45Alphabet !!) [b, a]
-- where
-- a = x1 `mod` 45
-- b = x1 `div` 45
-- encodeChunk _ = error "Invalid chunk length"
-- -- Decode
-- dec45 :: String -> String
-- dec45 encoded = bytesToChars decodedBytes
-- where
-- numericValues = map charToNumeric encoded
-- groups = groupIntoThrees numericValues
-- base45Values = map toBase45 groups
-- decodedBytes = concatMap fromBase45 base45Values
-- charToNumeric :: Char -> Int
-- charToNumeric c = case c of
-- '0' -> 0
-- '1' -> 1
-- '2' -> 2
-- '3' -> 3
-- '4' -> 4
-- '5' -> 5
-- '6' -> 6
-- '7' -> 7
-- '8' -> 8
-- '9' -> 9
-- 'A' -> 10
-- 'B' -> 11
-- 'C' -> 12
-- 'D' -> 13
-- 'E' -> 14
-- 'F' -> 15
-- 'G' -> 16
-- 'H' -> 17
-- 'I' -> 18
-- 'J' -> 19
-- 'K' -> 20
-- 'L' -> 21
-- 'M' -> 22
-- 'N' -> 23
-- 'O' -> 24
-- 'P' -> 25
-- 'Q' -> 26
-- 'R' -> 27
-- 'S' -> 28
-- 'T' -> 29
-- 'U' -> 30
-- 'V' -> 31
-- 'W' -> 32
-- 'X' -> 33
-- 'Y' -> 34
-- 'Z' -> 35
-- ' ' -> 36
-- '$' -> 37
-- '%' -> 38
-- '*' -> 39
-- '+' -> 40
-- '-' -> 41
-- '.' -> 42
-- '/' -> 43
-- ':' -> 44
-- _ -> error "Invalid Base45 character"
-- groupIntoThrees :: [Int] -> [[Int]]
-- groupIntoThrees [] = []
-- groupIntoThrees xs
-- | length xs < 3 = [xs ++ replicate (3 - length xs) 0]
-- | otherwise = take 3 xs : groupIntoThrees (drop 3 xs)
-- toBase45 :: [Int] -> Int
-- toBase45 [c, d, e] = c + d * 45 + e * (45 * 45)
-- fromBase45 :: Int -> [Int]
-- fromBase45 n
-- | n >= 256 = fromBase45 (n `div` 256) ++ [n `mod` 256]
-- | otherwise = [n]
-- bytesToChars :: [Int] -> String
-- bytesToChars = map chr
module Encoding.Base45
( enc45
, dec45
) where
import Data.Char (chr, ord)
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import Data.List (unfoldr)
import Data.Maybe (fromJust)
import Data.Word (Word8)
base45Alphabet :: ByteString
base45Alphabet = BC.pack $ ['0'..'9'] ++ ['A'..'Z'] ++ " " ++ "$%*+-./:"
enc45 :: ByteString -> ByteString
enc45 = BC.concat . map (BC.reverse . encodeChunk . map fromIntegral) . chunkBy 2 . B.unpack
chunkBy :: Int -> [a] -> [[a]]
chunkBy _ [] = []
chunkBy n xs = take n xs : chunkBy n (drop n xs)
encodeChunk :: [Int] -> ByteString
encodeChunk [x1, x2] = BC.pack $ map (BC.index base45Alphabet) [c, b, a]
where
n = x1 * 256 + x2
a = n `mod` 45
b = (n `div` 45) `mod` 45
c = n `div` 2025
encodeChunk [x1] = BC.pack $ map (BC.index base45Alphabet) [b, a]
where
a = x1 `mod` 45
b = x1 `div` 45
encodeChunk _ = error "Invalid chunk length"
dec45 :: ByteString -> ByteString
dec45 encoded = B.pack decodedBytes
where
numericValues = map charToNumeric (BC.unpack encoded)
groups = groupIntoThrees numericValues
base45Values = map toBase45 groups
decodedBytes = concatMap fromBase45 base45Values
charToNumeric :: Char -> Int
charToNumeric c = fromJust $ BC.elemIndex c base45Alphabet
groupIntoThrees :: [Int] -> [[Int]]
groupIntoThrees [] = []
groupIntoThrees xs
| length xs < 3 = [xs ++ replicate (3 - length xs) 0]
| otherwise = take 3 xs : groupIntoThrees (drop 3 xs)
toBase45 :: [Int] -> Int
toBase45 [c, d, e] = c + d * 45 + e * (45 * 45)
toBase45 _ = error "Invalid Base45 group"
-- fromBase45 :: Int -> [Int]
-- fromBase45 n = unfoldr (\x -> if x == 0 then Nothing else Just (x `mod` 256, x `div` 256)) n
fromBase45 :: Int -> [Word8]
fromBase45 n = reverse $ unfoldr (\x -> if x == 0 then Nothing else Just (fromIntegral $ x `mod` 256, x `div` 256)) n
bytesToChars :: [Int] -> [Char]
bytesToChars = map chr

View File

@ -3,19 +3,27 @@ module Encoding.Base58
, dec58 , dec58
) where ) where
import qualified Data.ByteString.Char8 as C import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import Data.ByteString.UTF8 as BSU -- from utf8-string import Data.ByteString.UTF8 as BSU -- from utf8-string
import qualified Haskoin.Address.Base58 as B58 import qualified Haskoin.Address.Base58 as B58
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
-- import qualified Data.Text.IO as T import qualified Data.Text.IO as T
dec58 :: String -> String -- dec58 :: String -> String
dec58 input = -- dec58 input =
case B58.decodeBase58 (T.pack input) of -- case B58.decodeBase58 (T.pack input) of
Just decodedStr -> T.unpack (T.decodeUtf8 decodedStr) -- Just decodedStr -> T.unpack (T.decodeUtf8 decodedStr)
Nothing -> "Error decoding Base58.\n" -- Nothing -> "Error decoding Base58.\n"
enc58 :: String -> String dec58 :: B.ByteString -> B.ByteString
enc58 = T.unpack . B58.encodeBase58 . BSU.fromString dec58 input = case B58.decodeBase58 (T.decodeUtf8 input) of
Just byteString -> byteString
Nothing -> BC.pack "Error: Invalid Base58 input"
-- enc58 :: String -> String
-- enc58 = T.unpack . B58.encodeBase58 . BSU.fromString
enc58 :: B.ByteString -> B.ByteString
enc58 = BC.pack . T.unpack . B58.encodeBase58

View File

@ -1,32 +1,91 @@
-- module Encoding.Base62
-- ( enc62
-- , dec62
-- ) where
-- import qualified Data.Word.Base62 as B62
-- import Text.Read (readMaybe)
-- import Data.Maybe (fromMaybe)
-- import Data.ByteString.UTF8 as BSU -- from utf8-string
-- import qualified Data.Bytes as Bytes
-- import Data.Bytes.Text.Latin1 as Latin1
-- import qualified Data.ByteString.Char8 as C
-- import qualified Data.Text as T
-- import qualified Data.Text.Encoding as T
-- -- import qualified Data.Text.IO as T
-- dec62 :: String -> String
-- dec62 input =
-- let decoded = B62.decode128 (Bytes.fromByteString (BSU.fromString input))
-- in fromMaybe "Error decoding Base62.\n" (show <$> decoded)
-- let decoded = BC.unpack $ B62.decode128
-- stringToInt :: String -> Maybe Integer
-- stringToInt = readMaybe
-- enc62 :: String -> String
-- enc62 input =
-- let intValue = fromMaybe (error "Error: Unable to convert input string to integer") (stringToInt input)
-- encoded = B62.encode64 (fromIntegral intValue)
-- encodedText = T.decodeUtf8 (BSU.fromString (Latin1.toString (Bytes.fromByteArray encoded)))
-- in T.unpack encodedText
module Encoding.Base62 module Encoding.Base62
( enc62 ( enc62
, dec62 , dec62
) where ) where
import qualified Data.ByteString.Char8 as BC
import qualified Data.Word.Base62 as B62 import qualified Data.ByteString as BS
import Text.Read (readMaybe) import Data.ByteString.Internal (c2w, w2c)
import Data.List (elemIndex)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Data.ByteString.UTF8 as BSU -- from utf8-string import Numeric (showIntAtBase)
import qualified Data.Bytes as Bytes import Data.Char (intToDigit)
import Data.Bytes.Text.Latin1 as Latin1
import qualified Data.ByteString.Char8 as C
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
-- import qualified Data.Text.IO as T import System.IO.Unsafe (unsafePerformIO)
import qualified Data.List as List
base62Chars :: String
base62Chars = ['0'..'9'] ++ ['A'..'Z'] ++ ['a'..'z']
dec62 :: String -> String -- Convert a ByteString to an Integer
dec62 input = byteStringToInteger :: BS.ByteString -> Integer
let decoded = B62.decode128 (Bytes.fromByteString (BSU.fromString input)) byteStringToInteger = BC.foldl' (\acc w -> acc * 256 + fromIntegral (c2w w)) 0
in fromMaybe "Error decoding Base62.\n" (show <$> decoded)
stringToInt :: String -> Maybe Integer -- Convert an Integer to a ByteString
stringToInt = readMaybe integerToByteString :: Integer -> BS.ByteString
integerToByteString 0 = BC.singleton (w2c 0)
integerToByteString i = BC.reverse $ BC.unfoldr step i
where
step 0 = Nothing
step x = Just (w2c (fromIntegral (x `mod` 256)), x `div` 256)
enc62 :: String -> String -- Encode an Integer to a Base62 ByteString
encodeBase62 :: Integer -> BS.ByteString
encodeBase62 0 = BC.singleton (base62Chars !! 0)
encodeBase62 n = BC.reverse $ BC.unfoldr step n
where
step 0 = Nothing
step x = let (q, r) = x `divMod` 62
in Just (base62Chars !! fromIntegral r, q)
decodeBase62 :: BS.ByteString -> Integer
decodeBase62 = BC.foldl' (\acc w -> acc * 62 + fromIntegral (fromMaybe 0 (elemIndex w base62Chars))) 0
where
elemIndex :: Char -> String -> Maybe Int
elemIndex c str = List.findIndex (== c) str
enc62 :: BC.ByteString -> BC.ByteString
enc62 input = enc62 input =
let intValue = fromMaybe (error "Error: Unable to convert input string to integer") (stringToInt input) let intValue = byteStringToInteger input
encoded = B62.encode64 (fromIntegral intValue) in encodeBase62 intValue
encodedText = T.decodeUtf8 (BSU.fromString (Latin1.toString (Bytes.fromByteArray encoded)))
in T.unpack encodedText dec62 :: BC.ByteString -> BC.ByteString
dec62 input =
let decoded = decodeBase62 input
in integerToByteString decoded

View File

@ -6,7 +6,8 @@ module Encoding.Base64
) where ) where
import Data.ByteString.UTF8 as BSU -- from utf8-string import Data.ByteString.UTF8 as BSU -- from utf8-string
import qualified Data.ByteString.Char8 as C import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import qualified Codec.Binary.Base64 as B64 import qualified Codec.Binary.Base64 as B64
import qualified Data.ByteString.Base64 as B64L import qualified Data.ByteString.Base64 as B64L
import qualified Codec.Binary.Base64Url as B64U import qualified Codec.Binary.Base64Url as B64U
@ -15,38 +16,56 @@ import qualified Data.Text as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
import qualified Data.Text.IO as T import qualified Data.Text.IO as T
encodeToBase64 :: C.ByteString -> Either String C.ByteString -- encodeToBase64 :: C.ByteString -> Either String C.ByteString
encodeToBase64 bs = -- encodeToBase64 bs =
case B64.encode bs of -- case B64.encode bs of
encoded | C.null encoded -> Left "Failed to encode Base64.\n" -- encoded | C.null encoded -> Left "Failed to encode Base64.\n"
| otherwise -> Right encoded -- | otherwise -> Right encoded
decodeFromBase64 :: C.ByteString -> Either String C.ByteString -- decodeFromBase64 :: C.ByteString -> Either String C.ByteString
decodeFromBase64 bs = -- decodeFromBase64 bs =
case B64L.decodeLenient bs of -- case B64L.decodeLenient bs of
decoded | C.null decoded -> Left "Failed to decode from Base64.\n" -- decoded | C.null decoded -> Left "Failed to decode from Base64.\n"
| otherwise -> Right decoded -- | otherwise -> Right decoded
-- | otherwise -> Right (BSU.toString decoded) -- | otherwise -> Right (BSU.toString decoded)
-- Left err -> Left $ "Failed to decode from base64: " ++ err -- Left err -> Left $ "Failed to decode from base64: " ++ err
-- Right decoded -> Right decoded -- Right decoded -> Right decoded
dec64 :: String -> String -- dec64 :: String -> String
dec64 input = -- dec64 input =
case decodeFromBase64 (BSU.fromString input) of -- case decodeFromBase64 (BSU.fromString input) of
Right byteString -> T.unpack (T.decodeUtf8 byteString) -- Right byteString -> T.unpack (T.decodeUtf8 byteString)
Left errMsg -> "Error: " ++ errMsg -- 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 -- enc64 :: String -> String
dec64url input = -- enc64 input =
case B64.decode (BSU.fromString input) of -- case encodeToBase64 (BSU.fromString input) of
Right decoded -> T.unpack (T.decodeUtf8 decoded) -- Right byteString -> C.unpack byteString
Left _ -> "Error decoding Base64 for URLs.\n" -- Left errMsg -> "Error: " ++ errMsg
enc64url :: String -> String dec64 :: B.ByteString -> B.ByteString
enc64url = C.unpack . B64U.encode . BSU.fromString dec64 input = case B64.decode input of
Right byteString -> byteString
Left _ -> BC.pack "Error: Invalid Base64 input"
enc64 :: B.ByteString -> B.ByteString
enc64 = B64.encode
-- dec64url :: String -> String
-- dec64url input =
-- case B64.decode (BSU.fromString input) of
-- Right decoded -> T.unpack (T.decodeUtf8 decoded)
-- Left _ -> "Error decoding Base64 for URLs.\n"
-- enc64url :: String -> String
-- enc64url = C.unpack . B64U.encode . BSU.fromString
-- https://datatracker.ietf.org/doc/html/rfc4648#section-5
dec64url :: B.ByteString -> B.ByteString
dec64url input = case B64U.decode input of
Right byteString -> byteString
Left _ -> BC.pack "Error: Invalid Base64URL input"
enc64url :: B.ByteString -> B.ByteString
enc64url = B64U.encode

View File

@ -1,30 +1,60 @@
-- 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
module Encoding.Base8 module Encoding.Base8
( enc8 ( enc8
, dec8 , dec8
) where ) where
import Data.Char (ord, chr, intToDigit) import Data.Char (ord, chr, intToDigit)
import qualified Data.ByteString.Char8 as BC
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
octalToChar :: String -> Char octalToChar :: ByteString -> Char
octalToChar octal = chr (read ("0o" ++ octal)) -- Assumes input is in base 8 (octal) octalToChar octal = chr (read ("0o" ++ BC.unpack octal)) -- Assumes input is in base 8 (octal)
-- Function to split a string into chunks of three characters each chunksOf :: Int -> ByteString -> [ByteString]
chunksOf3 :: String -> [String] chunksOf n bs
chunksOf3 [] = [] | B.null bs = []
chunksOf3 str = Prelude.take 3 str : chunksOf3 (Prelude.drop 3 str) | otherwise = BC.take n bs : chunksOf n (BC.drop n bs)
dec8 :: String -> String dec8 :: ByteString -> ByteString
dec8 = map octalToChar . words dec8 = BC.pack . map octalToChar . BC.words
chunksOf :: Int -> [a] -> [[a]] unicodeToOctal :: Char -> [ByteString]
chunksOf _ [] = [] unicodeToOctal c = chunksOf 3 (BC.pack $ reverse $ decimalToOctal' (ord c))
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 where
decimalToOctal' 0 = "0" decimalToOctal' 0 = "0"
decimalToOctal' m = let (q, r) = m `divMod` 8 in intToDigit r : if q == 0 then "" else decimalToOctal' q decimalToOctal' m = let (q, r) = m `divMod` 8 in intToDigit r : if q == 0 then "" else decimalToOctal' q
enc8 :: String -> String enc8 :: ByteString -> ByteString
enc8 = unwords . concatMap unicodeToOctal enc8 = BC.unwords . concatMap unicodeToOctal . BC.unpack

View File

@ -5,17 +5,25 @@ module Encoding.Base85
import qualified Codec.Binary.Base85 as B85 import qualified Codec.Binary.Base85 as B85
import Data.ByteString.UTF8 as BSU -- from utf8-string import Data.ByteString.UTF8 as BSU -- from utf8-string
import qualified Data.ByteString.Char8 as C import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
dec85 :: String -> String -- dec85 :: String -> String
dec85 input = -- dec85 input =
case B85.decode (BSU.fromString input) of -- case B85.decode (BSU.fromString input) of
Right decodedStr -> T.unpack (T.decodeUtf8 decodedStr) -- Right decodedStr -> T.unpack (T.decodeUtf8 decodedStr)
Left _ -> "Error decoding Base85.\n" -- Left _ -> "Error decoding Base85.\n"
enc85 :: String -> String dec85 :: B.ByteString -> B.ByteString
enc85 = C.unpack . B85.encode . BSU.fromString dec85 input = case B85.decode input of
Right byteString -> byteString
Left _ -> BC.pack "Error: Invalid Base85 input"
-- enc85 :: String -> String
-- enc85 = C.unpack . B85.encode . BSU.fromString
enc85 :: B.ByteString -> B.ByteString
enc85 = B85.encode

View File

@ -3,6 +3,8 @@ module Encoding.Base91
, dec91 , dec91
) where ) where
import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString.Char8 as C import qualified Data.ByteString.Char8 as C
import Data.ByteString.UTF8 as BSU import Data.ByteString.UTF8 as BSU
import qualified Codec.Binary.Base91 as B91 import qualified Codec.Binary.Base91 as B91
@ -10,8 +12,12 @@ import qualified Data.Text as T
-- import qualified Data.Text.IO as T -- import qualified Data.Text.IO as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
dec91 :: String -> String -- dec91 :: String -> String
dec91 = T.unpack . T.decodeUtf8 . B91.decode -- dec91 = T.unpack . T.decodeUtf8 . B91.decode
dec91 :: B.ByteString -> B.ByteString
dec91 = B91.decode . BC.unpack
enc91 :: String -> String -- enc91 :: String -> String
enc91 = B91.encode . BSU.fromString -- enc91 = B91.encode . BSU.fromString
enc91 :: B.ByteString -> B.ByteString
enc91 = BC.pack . B91.encode

View File

@ -0,0 +1,30 @@
module Encoding.LetterToNumber
( encltn
, decltn
) where
import Data.Char (ord, chr, isAscii, isAlpha, isSpace, isDigit, toUpper)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BC
-- This encodes ASCII characters only and ignores all other characters
charToNumber :: Char -> ByteString
charToNumber c
| not (isAscii c) = BC.pack ""
| isAlpha c = BC.pack $ show $ ord (toUpper c) - ord 'A' + 1
| isSpace c = BC.pack "0"
| otherwise = BC.singleton c
numberToChar :: ByteString -> ByteString
numberToChar s
| s == BC.pack "0" = BC.singleton ' '
| BC.all isDigit s = BC.singleton $ chr $ (read $ BC.unpack s) + ord 'A' - 1
| otherwise = s
encltn :: ByteString -> ByteString
encltn input = BC.unwords $ filter (not . BC.null) $ map charToNumber $ BC.unpack input
decltn :: ByteString -> ByteString
decltn input = BC.concat $ map numberToChar $ BC.words input

21
src/Encoding/Morse.hs Normal file
View File

@ -0,0 +1,21 @@
module Encoding.Morse
( encmorse
, decmorse
) where
import Text.Morse as M
import Data.ByteString (ByteString)
import Data.Char (isSpace)
import qualified Data.ByteString.Char8 as BC
encmorse :: ByteString -> ByteString
encmorse input = BC.pack $ encodeValidMorseChars (BC.unpack input)
where
encodeValidMorseChars :: String -> String
encodeValidMorseChars = concatMap (\c -> M.encodeMorse [c])
decmorse :: ByteString -> ByteString
decmorse input = case M.decodeMorse (BC.unpack input) of
"" -> BC.pack "Invalid Morse Code"
decoded -> BC.pack decoded

View File

@ -3,20 +3,27 @@ module Encoding.QuotedPrintable
, decqp , decqp
) where ) where
import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import qualified Codec.Binary.QuotedPrintable as QP import qualified Codec.Binary.QuotedPrintable as QP
import Data.ByteString.UTF8 as BSU -- from utf8-string import Data.ByteString.UTF8 as BSU -- from utf8-string
import qualified Data.ByteString.Char8 as C -- import qualified Data.ByteString.Char8 as C
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
-- import qualified Data.Text.IO as T -- import qualified Data.Text.IO as T
decqp :: String -> String -- decqp :: String -> String
decqp input = -- decqp input =
case QP.decode (BSU.fromString input) of -- case QP.decode (BSU.fromString input) of
Right decoded -> T.unpack (T.decodeUtf8 decoded) -- Right decoded -> T.unpack (T.decodeUtf8 decoded)
Left _ -> "Error decoding QP.\n" -- Left _ -> "Error decoding QP.\n"
decqp :: B.ByteString -> B.ByteString
encqp :: String -> String decqp input = case QP.decode input of
encqp = C.unpack . QP.encode . BSU.fromString Right byteString -> byteString
Left _ -> BC.pack "Error: Invalid Quoted Printable input"
-- encqp :: String -> String
-- encqp = C.unpack . QP.encode . BSU.fromString
encqp :: B.ByteString -> B.ByteString
encqp = QP.encode

View File

@ -2,21 +2,33 @@ module Encoding.Rotate
( rotate ) where ( rotate ) where
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
upperCase = ['A' .. 'Z'] upperCase = BC.pack ['A' .. 'Z']
lowerCase = ['a' .. 'z'] lowerCase = BC.pack ['a' .. 'z']
-- rotate :: Int * -> String -- rotate :: Int -> String -> String
rotate :: Int -> String -> String -- rotate n s = map (rotchar n) s
rotate n s = map (rotchar n) s -- where
-- rotchar n c =
-- case (lookup c $ transp n lowerCase) of
-- Just x -> x
-- Nothing -> fromMaybe c (lookup c $ transp n upperCase)
rotate :: Int -> BC.ByteString -> BC.ByteString
rotate n s = BC.map (rotchar n) s
where where
rotchar :: Int -> Char -> Char
rotchar n c = rotchar n c =
case (lookup c $ transp n lowerCase) of case (lookup c $ transp n lowerCase) of
Just x -> x Just x -> x
Nothing -> fromMaybe c (lookup c $ transp n upperCase) Nothing -> fromMaybe c (lookup c $ transp n upperCase)
transp :: Int -> [Char] -> [(Char, Char)]
transp n x = zip x ((drop n x) ++ (take n x)) -- transp :: Int -> [Char] -> [(Char, Char)]
-- transp n x = zip x ((drop n x) ++ (take n x))
transp :: Int -> BC.ByteString -> [(Char, Char)]
transp n x = Prelude.zip (BC.unpack x) (BC.unpack $ BC.append (BC.drop n x) (BC.take n x))

58
src/Encoding/Solve.hs Normal file
View File

@ -0,0 +1,58 @@
module Encoding.Solve
(solveEnc) where
import qualified Data.ByteString.Char8 as BC
import Text.Regex.TDFA
import Encoding.Base2 (enc2, dec2)
import Encoding.Base8 (enc8, dec8)
import Encoding.Base10 (enc10, dec10)
import Encoding.Base16 (enc16, dec16)
import Encoding.Base32 (enc32, dec32)
import Encoding.Base45 (enc45, dec45)
import Encoding.Base58 (enc58, dec58)
import Encoding.Base62 (enc62, dec62)
import Encoding.Base64 (enc64, dec64, enc64url, dec64url)
import Encoding.Base85 (enc85, dec85)
import Encoding.Base91 (enc91, dec91)
import Encoding.Url (encurl, decurl)
import Encoding.Xx (encxx, decxx)
import Encoding.QuotedPrintable (encqp, decqp)
import Encoding.UnixToUnix (encuu, decuu)
import Encoding.Yenc (ency, decy)
import Encoding.Rotate (rotate)
base91Regex = "^[!-~]*$"
base85Regex = "^[0-9A-Za-z!#$%&()*+,-;<=>?@^_`{|}~]+$"
base64Regex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$"
base58Regex = "^[1-9A-HJ-NP-Za-km-z]+$" -- incorrect
base32Regex = "^(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=)?$"
base16Regex = "^[0-9A-FXx]*$"
base10Regex = "^[0-9 ]*$"
base8Regex = "^[0-7 ]*$"
base2Regex = "^[01 ]*$"
urlRegex = "^[a-zA-Z0-9%]*$"
solveEnc :: BC.ByteString -> BC.ByteString
solveEnc input =
let isBase91 = input =~ base91Regex :: Bool
isBase85 = input =~ base85Regex :: Bool
isBase64 = input =~ base64Regex :: Bool
isBase58 = input =~ base58Regex :: Bool
isBase32 = input =~ base32Regex :: Bool
isBase16 = input =~ base16Regex :: Bool
isBase10 = input =~ base10Regex :: Bool
isBase8 = input =~ base8Regex :: Bool
isBase2 = input =~ base2Regex :: Bool
isURL = input =~ urlRegex :: Bool
base91Result = if isBase91 then BC.pack "\nBase91:\n" `BC.append` dec91 input else BC.empty
base85Result = if isBase85 then BC.pack "\nBase85:\n" `BC.append` dec85 input else BC.empty
base64Result = if isBase64 then BC.pack "\nBase64:\n" `BC.append` dec64 input else BC.empty
base58Result = if isBase58 then BC.pack "\nBase58:\n" `BC.append` dec58 input else BC.empty
base32Result = if isBase64 then BC.pack "\nBase32:\n" `BC.append` dec32 input else BC.empty
base16Result = if isBase16 then BC.pack "\nBase16:\n" `BC.append` dec16 input else BC.empty
base10Result = if isBase10 then BC.pack "\nBase10:\n" `BC.append` dec10 input else BC.empty
base2Result = if isBase2 then BC.pack "\nBase2:\n" `BC.append` dec2 input else BC.empty
base8Result = if isBase8 then BC.pack "\nBase8:\n" `BC.append` dec8 input else BC.empty
urlResult = if isURL then BC.pack "\nTrying URL decode:\n" `BC.append` decurl input else BC.empty
in BC.concat [base91Result, base85Result, base64Result, base58Result, base32Result, base16Result, base10Result, base8Result, base2Result, urlResult]

47
src/Encoding/Tap.hs Normal file
View File

@ -0,0 +1,47 @@
{-# LANGUAGE OverloadedStrings #-}
module Encoding.Tap
( enctap
, dectap
) where
import Data.Char (isAsciiUpper, isAsciiLower, toLower, chr, ord, toUpper)
import Data.List (find)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BC
enctap :: ByteString -> ByteString
enctap = BC.concatMap encodeChar
where
encodeChar ' ' = BC.singleton ' '
encodeChar 'K' = BC.pack "22" -- Special case: 'K' is encoded as "22"
encodeChar c
| isAsciiUpper c || isAsciiLower c =
let (row, col) = positionInGrid c
in BC.pack [chr (ord '0' + row), chr (ord '0' + col)]
| otherwise = BC.empty -- Handle non-alphabet characters or errors
positionInGrid c =
let idx = ord (toUpper c) - ord 'A'
row = idx `div` 5 + 1
col = idx `mod` 5 + 1
in (row, col)
dectap :: ByteString -> ByteString
dectap = BC.concat . map decodePair . chunkPairs . BC.filter (/= ' ')
where
chunkPairs :: ByteString -> [ByteString]
chunkPairs bs
| BC.null bs = []
| otherwise = let (pair, rest) = BC.splitAt 2 bs in pair : chunkPairs rest
decodePair pair
| pair == "22" = BC.singleton 'K' -- Special case: "22" is decoded as 'K'
| BC.length pair == 2 =
let [row, col] = BC.unpack pair
rowIdx = ord row - ord '0'
colIdx = ord col - ord '0'
idx = (rowIdx - 1) * 5 + (colIdx - 1)
in BC.singleton $ chr (ord 'A' + idx)
| otherwise = error $ "Invalid Tap Code sequence: " ++ show pair

63
src/Encoding/Unary.hs Normal file
View File

@ -0,0 +1,63 @@
module Encoding.Unary
( encunary
, decunary
) where
import Data.ByteString (ByteString)
import Data.List (group)
import qualified Data.ByteString.Char8 as BC
import Encoding.Base2 (dec2, enc2, binaryToChar)
import Debug.Trace (trace)
encodeChuckNorris :: ByteString -> ByteString
encodeChuckNorris binary =
let cleanBinary = BC.filter (/= ' ') binary
in BC.unwords . concatMap encodeRunLength . group $ BC.unpack cleanBinary
where
encodeRunLength :: String -> [ByteString]
encodeRunLength xs@(x:_) = [prefix x, BC.pack (replicate (length xs) '0')]
encodeRunLength [] = []
prefix '0' = BC.pack "00"
prefix '1' = BC.pack "0"
prefix c = error $ "Invalid binary character encoding" ++ show c
pairs :: [a] -> [(a, a)]
pairs (x:y:rest) = (x, y) : pairs rest
pairs _ = []
encunary :: ByteString -> ByteString
encunary input = encodeChuckNorris $ enc2 input
decodeChuckNorris :: ByteString -> ByteString
decodeChuckNorris encoded = BC.pack . concatMap (BC.unpack . decodeRunLength) . pairs . BC.words $ encoded
where
decodeRunLength :: (ByteString, ByteString) -> ByteString
decodeRunLength (prefix, zeros)
| prefix == BC.pack "00" = BC.replicate (BC.length zeros) '0'
| prefix == BC.pack "0" = BC.replicate (BC.length zeros) '1'
| otherwise = error "Invalid Unary encoding"
-- pairs (x:y:rest) = (x, y) : pairs rest
-- pairs _ = []
-- decodeRunLength ("00", zeros) = replicate (BC.length zeros) '0'
-- decodeRunLength ("0", zeros) = replicate (BC.length zeros) '1'
-- decodeRunLength _ = error "Invalid Unary encoding"
decunary :: ByteString -> ByteString
decunary encoded =
let binaryStr = decodeChuckNorris encoded
in BC.pack $ map binaryToChar (chunkBinaryString binaryStr)
where
chunkBinaryString :: ByteString -> [ByteString]
chunkBinaryString bs
| BC.null bs = []
| otherwise = let (chunk, rest) = BC.splitAt 8 bs
in chunk : chunkBinaryString rest
-- encunary input =
-- let binaryStr = enc2 input
-- in trace (show binaryStr) $ encodeChuckNorris binaryStr
-- decunary :: ByteString -> ByteString
-- decunary encoded = dec2 $ decodeChuckNorris encoded

View File

@ -1,23 +1,115 @@
-- module Encoding.UnixToUnix
-- ( encuu
-- , decuu
-- ) where
-- import Data.ByteString as B
-- import qualified Data.ByteString.Char8 as BC
-- import qualified Codec.Binary.Uu as UU
-- import Data.ByteString.UTF8 as BSU -- from utf8-string
-- import qualified Data.Text as T
-- import qualified Data.Text.Encoding as T
-- import qualified Data.Text.IO as T
-- -- decuu :: String -> String
-- -- -- decuu = C.unpack . U.fromRight . UU.decode . BSU.fromString
-- -- decuu input =
-- -- case UU.decode (T.encodeUtf8 (T.pack input)) of
-- -- Right decoded -> T.unpack (T.decodeUtf8 decoded)
-- -- Left _ -> "Error decoding UU.\n"
-- decuu :: B.ByteString -> B.ByteString
-- decuu input = case UU.decode input of
-- Right byteString -> byteString
-- Left _ -> BC.pack "Error: Invalid Unix to Unix encoding input"
-- -- encuu :: String -> String
-- -- -- encuu = C.unpack . UU.encode . BSU.fromString
-- -- encuu = T.unpack . T.decodeUtf8 . UU.encode . T.encodeUtf8 . T.pack
-- encuu :: B.ByteString -> B.ByteString
-- encuu = UU.encode
module Encoding.UnixToUnix module Encoding.UnixToUnix
( encuu ( encuu
, decuu , decuu
) where ) where
import qualified Codec.Binary.Uu as UU import Data.Bits (shiftL, shiftR, (.&.), (.|.))
import Data.ByteString.UTF8 as BSU -- from utf8-string import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as C import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import Data.Char (chr, ord)
import Data.Word (Word8)
import Data.List (unfoldr)
import qualified Data.Text as T uuAlphabet :: String
import qualified Data.Text.Encoding as T uuAlphabet = " !" ++ ['"'..'~']
import qualified Data.Text.IO as T
decuu :: String -> String -- Convert a 6-bit integer to a UUEncode character
-- decuu = C.unpack . U.fromRight . UU.decode . BSU.fromString toUUChar :: Int -> Char
decuu input = toUUChar n = uuAlphabet !! n
case UU.decode (BSU.fromString input) of
Right decoded -> T.unpack (T.decodeUtf8 decoded)
Left _ -> "Error decoding UU.\n"
encuu :: String -> String -- Convert a UUEncode character to a 6-bit integer
encuu = C.unpack . UU.encode . BSU.fromString fromUUChar :: Char -> Int
fromUUChar c = maybe (error "Invalid UUEncode character") id (lookup c (zip uuAlphabet [0..]))
encuu :: ByteString -> ByteString
encuu bs = BC.concat . map encodeLine . chunkBy 45 $ B.unpack bs
where
encodeLine :: [Word8] -> ByteString
encodeLine line =
let lenChar = toUUChar (length line)
encodedData = concatMap (map toUUChar . encodeChunk) (chunkBy 3 line)
in BC.pack (lenChar : encodedData)
encodeChunk :: [Word8] -> [Int]
encodeChunk [x1, x2, x3] = [ fromIntegral ((x1 `shiftR` 2) .&. 0x3F)
, fromIntegral (((x1 `shiftL` 4) .&. 0x30) .|. ((x2 `shiftR` 4) .&. 0x0F))
, fromIntegral (((x2 `shiftL` 2) .&. 0x3C) .|. ((x3 `shiftR` 6) .&. 0x03))
, fromIntegral (x3 .&. 0x3F)
]
encodeChunk [x1, x2] = [ fromIntegral ((x1 `shiftR` 2) .&. 0x3F)
, fromIntegral (((x1 `shiftL` 4) .&. 0x30) .|. ((x2 `shiftR` 4) .&. 0x0F))
, fromIntegral ((x2 `shiftL` 2) .&. 0x3C)
]
encodeChunk [x1] = [ fromIntegral ((x1 `shiftR` 2) .&. 0x3F)
, fromIntegral ((x1 `shiftL` 4) .&. 0x30)
]
encodeChunk _ = error "Invalid chunk length"
decuu :: ByteString -> ByteString
decuu = B.concat . map decodeLine . BC.lines
where
decodeLine :: ByteString -> ByteString
decodeLine line =
let lenChar = BC.head line
len = fromUUChar lenChar
encodedData = BC.unpack (BC.tail line)
in B.pack $ take len (concatMap decodeChunk (chunkBy 4 encodedData))
decodeChunk :: [Char] -> [Word8]
decodeChunk [c1, c2, c3, c4] =
let n1 = fromUUChar c1
n2 = fromUUChar c2
n3 = fromUUChar c3
n4 = fromUUChar c4
in [ fromIntegral ((n1 `shiftL` 2) .|. (n2 `shiftR` 4))
, fromIntegral ((n2 `shiftL` 4) .|. (n3 `shiftR` 2))
, fromIntegral ((n3 `shiftL` 6) .|. n4)
]
decodeChunk [c1, c2, c3] =
let n1 = fromUUChar c1
n2 = fromUUChar c2
n3 = fromUUChar c3
in [ fromIntegral ((n1 `shiftL` 2) .|. (n2 `shiftR` 4))
, fromIntegral ((n2 `shiftL` 4) .|. (n3 `shiftR` 2))
]
decodeChunk [c1, c2] =
let n1 = fromUUChar c1
n2 = fromUUChar c2
in [ fromIntegral ((n1 `shiftL` 2) .|. (n2 `shiftR` 4))]
decodeChunk _ = error "Invalid encoded chunk length"
chunkBy :: Int -> [a] -> [[a]]
chunkBy _ [] = []
chunkBy n xs = take n xs : chunkBy n (drop n xs)

View File

@ -4,10 +4,12 @@ module Encoding.Url
) where ) where
import qualified Network.HTTP.Base as HB import qualified Network.HTTP.Base as HB
import Data.ByteString as B
import Data.ByteString.UTF8 as BSU
decurl :: String -> String decurl :: B.ByteString -> B.ByteString
decurl = HB.urlDecode decurl = BSU.fromString . HB.urlDecode . BSU.toString
encurl :: String -> String encurl :: B.ByteString -> B.ByteString
encurl = HB.urlEncode encurl = BSU.fromString . HB.urlEncode . BSU.toString

View File

@ -3,18 +3,15 @@ module Encoding.Xx
, decxx , decxx
) where ) where
import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import qualified Codec.Binary.Xx as XX import qualified Codec.Binary.Xx as XX
import Data.ByteString.UTF8 as BSU -- from utf8-string -- import Data.ByteString.UTF8 as BSU -- from utf8-string
import qualified Data.ByteString.Char8 as C
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Data.Text.IO as T
decxx :: String -> String decxx :: B.ByteString -> B.ByteString
decxx input = decxx input = case XX.decode input of
case XX.decode (BSU.fromString input) of Right byteString -> byteString
Right decoded -> T.unpack (T.decodeUtf8 decoded) Left _ -> BC.pack "Error: Invalid XX encoding input"
Left _ -> "Error decoding XX.\n"
encxx :: String -> String encxx :: B.ByteString -> B.ByteString
encxx = C.unpack . XX.encode . BSU.fromString encxx = XX.encode

View File

@ -4,20 +4,28 @@ module Encoding.Yenc
) where ) where
import Data.ByteString as B
import qualified Data.ByteString.Char8 as BC
import Data.ByteString.UTF8 as BSU -- from utf8-string import Data.ByteString.UTF8 as BSU -- from utf8-string
import qualified Data.ByteString.Char8 as C
import qualified Codec.Binary.Yenc as Y import qualified Codec.Binary.Yenc as Y
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Encoding as T import qualified Data.Text.Encoding as T
import qualified Data.Text.IO as T import qualified Data.Text.IO as T
decy :: String -> String -- decy :: String -> String
-- decy = C.unpack . U.fromRight . Y.decode . BSU.fromString -- -- decy = C.unpack . U.fromRight . Y.decode . BSU.fromString
decy input = -- decy input =
case Y.decode (BSU.fromString input) of -- case Y.decode (BSU.fromString input) of
Right decoded -> T.unpack (T.decodeUtf8 decoded) -- Right decoded -> T.unpack (T.decodeUtf8 decoded)
Left _ -> "Error decoding Y.\n" -- Left _ -> "Error decoding Y.\n"
ency :: String -> String decy :: B.ByteString -> B.ByteString
ency = C.unpack . Y.encode . BSU.fromString decy input = case Y.decode input of
Right byteString -> byteString
Left _ -> BC.pack "Error: Invalid YEncoding input"
-- ency :: String -> String
-- ency = C.unpack . Y.encode . BSU.fromString
ency :: B.ByteString -> B.ByteString
ency = Y.encode

View File

@ -1,89 +1,275 @@
module Main where module Main where
import Test.HUnit import Test.HUnit
import Encoding.Base64 (enc64, dec64) import Data.ByteString as B
import Data.ByteString.UTF8 as BSU
import Encoding.Base91 (enc91, dec91)
import Encoding.Base85 (enc85, dec85)
import Encoding.Base64 (enc64, dec64, enc64url, dec64url)
import Encoding.Url (encurl, decurl)
import Encoding.Base62 (enc62, dec62)
import Encoding.Base45 (enc45, dec45)
import Encoding.Base32 (enc32, dec32) import Encoding.Base32 (enc32, dec32)
import Encoding.Base16 (enc16, dec16) import Encoding.Base16 (enc16, dec16)
import Encoding.Base10 (enc10, dec10)
import Encoding.Base8 (enc8, dec8) import Encoding.Base8 (enc8, dec8)
import Encoding.Base2 (enc2, dec2) import Encoding.Base2 (enc2, dec2)
import Encoding.QuotedPrintable (encqp, decqp)
import Encoding.UnixToUnix (encuu, decuu)
import Encoding.Xx (encxx, decxx)
import Encoding.Yenc (ency, decy)
import Encoding.Rotate (rotate)
import System.Exit (exitFailure, exitSuccess) import System.Exit (exitFailure, exitSuccess)
-- Test cases for enc64 function helloWorldBS :: B.ByteString
helloWorldBS = BSU.fromString "Hello, World!"
haskellBS :: B.ByteString
haskellBS = BSU.fromString "Haskell"
emojiBS :: B.ByteString
emojiBS = BSU.fromString "😂"
testEnc91 :: Test
testEnc91 = TestCase $ do
assertEqual "for (enc91 \"Hello, World!\")," (BSU.fromString ">OwJh>}AQ;r@@Y?F") (enc91 helloWorldBS)
assertEqual "for (enc91 \"Haskell\")," (BSU.fromString "3D8=d,[*G") (enc91 haskellBS)
assertEqual "for (enc91 \"😂\")," (BSU.fromString "=~m6g") (enc91 emojiBS)
testDec91 :: Test
testDec91 = TestCase $ do
assertEqual "for (dec91 \">OwJh>}AQ;r@@Y?F\")," helloWorldBS (dec91 $ BSU.fromString ">OwJh>}AQ;r@@Y?F")
assertEqual "for (dec91 \"3D8=d,[*G\")," haskellBS (dec91 $ BSU.fromString "3D8=d,[*G")
assertEqual "for (dec91 \"=~m6g\")," emojiBS (dec91 $ BSU.fromString "=~m6g")
testEnc85 :: Test
testEnc85 = TestCase $ do
assertEqual "for (enc85 \"Hello, World!\")," (BSU.fromString "87cURD_*#4DfTZ)+T") (enc85 helloWorldBS)
assertEqual "for (enc85 \"Haskell\")," (BSU.fromString "87?RTASc/") (enc85 haskellBS)
assertEqual "for (enc85 \"😂\")," (BSU.fromString "n=Q)\"") (enc85 emojiBS)
testDec85 :: Test
testDec85 = TestCase $ do
assertEqual "for (dec85 \"87cURD_*#4DfTZ)+T\")," helloWorldBS (dec85 $ BSU.fromString "87cURD_*#4DfTZ)+T")
assertEqual "for (dec85 \"87?RTASc/\")," haskellBS (dec85 $ BSU.fromString "87?RTASc/")
assertEqual "for (dec85 \"n=Q)\"\")," emojiBS (dec85 $ BSU.fromString "n=Q)\"")
testEnc64 :: Test testEnc64 :: Test
testEnc64 = TestCase $ do testEnc64 = TestCase $ do
assertEqual "for (enc64 \"hello\")," "aGVsbG8=" (enc64 "hello") assertEqual "for (enc64 \"Hello, World!\")," (BSU.fromString "SGVsbG8sIFdvcmxkIQ==") (enc64 helloWorldBS)
assertEqual "for (enc64 \"Haskell\")," "SGFza2VsbA==" (enc64 "Haskell") assertEqual "for (enc64 \"Haskell\")," (BSU.fromString "SGFza2VsbA==") (enc64 haskellBS)
assertEqual "for (enc64 \"\x00\x01\x02\")," "AAEC" (enc64 "\x00\x01\x02") assertEqual "for (enc64 \"\x00\x01\x02\")," (BSU.fromString "AAEC") (enc64 $ BSU.fromString "\x00\x01\x02")
assertEqual "for (enc64 \"😂\")," "8J+Ygg==" (enc64 "😂") -- assertEqual "for (dec64 \"\xFB\xFF\")," (BSU.fromString "+/8=") (dec64 $ BSU.fromString "\xFB\xFF")
assertEqual "for (enc64 \"😂\")," (BSU.fromString "8J+Ygg==") (enc64 emojiBS)
-- Test cases for dec64 function
testDec64 :: Test testDec64 :: Test
testDec64 = TestCase $ do testDec64 = TestCase $ do
assertEqual "for (dec64 \"aGVsbG8=\")," "hello" (dec64 "aGVsbG8=") assertEqual "for (dec64 \"SGVsbG8sIFdvcmxkIQ==\")," helloWorldBS (dec64 $ BSU.fromString "SGVsbG8sIFdvcmxkIQ==")
assertEqual "for (dec64 \"SGFza2VsbA==\")," "Haskell" (dec64 "SGFza2VsbA==") assertEqual "for (dec64 \"SGFza2VsbA==\")," haskellBS (dec64 $ BSU.fromString "SGFza2VsbA==")
assertEqual "for (dec64 \"AAEC\")," "\x00\x01\x02" (dec64 "AAEC") assertEqual "for (dec64 \"AAEC\")," (BSU.fromString "\x00\x01\x02") (dec64 $ BSU.fromString "AAEC")
assertEqual "for (dec64 \"8J+Ygg==\")," "😂" (dec64 "8J+Ygg==") -- assertEqual "for (dec64 \"+/8=\")," (BSU.fromString "\xFB\xFF") (dec64 $ BSU.fromString "+/8=")
assertEqual "for (dec64 \"8J+Ygg==\")," (BSU.fromString "😂") (dec64 $ BSU.fromString "8J+Ygg==")
testDec32 :: Test testEnc64Url :: Test
testDec32 = TestCase $ do testEnc64Url = TestCase $ do
assertEqual "for (dec32 \"JBSWY3DPFQQFO33SNRSCC===\")," "Hello, World!" (dec32 "JBSWY3DPFQQFO33SNRSCC===") assertEqual "for (enc64url \"Hello, World!\")," (BSU.fromString "SGVsbG8sIFdvcmxkIQ==") (enc64url helloWorldBS)
assertEqual "for (dec32 \"JBQXG23FNRWA====\")," "Haskell" (dec32 "JBQXG23FNRWA====") assertEqual "for (enc64url \"Haskell\")," (BSU.fromString "SGFza2VsbA==") (enc64url haskellBS)
-- assertEqual "for (dec32 \"AAEC\")," "\x00\x01\x02" (dec32 "AAEC") assertEqual "for (enc64url \"\x00\x01\x02\")," (BSU.fromString "AAEC") (enc64url $ BSU.fromString "\x00\x01\x02")
assertEqual "for (dec32 \"6CPZRAQ=\")," "😂" (dec32 "6CPZRAQ=") -- assertEqual "for (enc64url \"\xFB\xFF\")," (BSU.fromString "-_8=") (enc64url $ BSU.fromString "\xFB\xFF")
assertEqual "for (enc64url \"😂\")," (BSU.fromString "8J-Ygg==") (enc64url emojiBS)
testDec64Url :: Test
testDec64Url = TestCase $ do
assertEqual "for (dec64url \"SGVsbG8sIFdvcmxkIQ==\")," helloWorldBS (dec64url $ BSU.fromString "SGVsbG8sIFdvcmxkIQ==")
assertEqual "for (dec64url \"SGFza2VsbA==\")," haskellBS (dec64url $ BSU.fromString "SGFza2VsbA==")
assertEqual "for (dec64url \"AAEC\")," (BSU.fromString "\x00\x01\x02") (dec64url $ BSU.fromString "AAEC")
-- assertEqual "for (dec64url \"-_8=\")," (BSU.fromString "\xFB\xFF") (dec64url $ BSU.fromString "-_8=")
assertEqual "for (dec64url \"8J-Ygg==\")," (BSU.fromString "😂") (dec64url $ BSU.fromString "8J-Ygg==")
testEncUrl :: Test
testEncUrl = TestCase $ do
assertEqual "for (encurl \"Hello, World\")," (BSU.fromString "Hello%2C%20World%21") (encurl helloWorldBS)
assertEqual "for (encurl \"http://example.com/?page=index.php\")," (BSU.fromString "http%3A%2F%2Fexample.com%2F%3Fpage%3Dindex.php") (encurl $ BSU.fromString "http://example.com/?page=index.php")
assertEqual "for (encurl \"😂\")," (BSU.fromString "%F0%9F%98%82") (encurl emojiBS)
testDecUrl :: Test
testDecUrl = TestCase $ do
assertEqual "for (decurl \"Hello%2C%20World%21\")," helloWorldBS (decurl $ BSU.fromString "Hello%2C%20World%21")
assertEqual "for (decurl \"http%3A%2F%2Fexample.com%2F%3Fpage%3Dindex.php\")," (BSU.fromString "http://example.com/?page=index.php") (decurl $ BSU.fromString "http%3A%2F%2Fexample.com%2F%3Fpage%3Dindex.php")
assertEqual "for (decurl \"%F0%9F%98%82\")," (BSU.fromString "😂") (decurl $ BSU.fromString "%F0%9F%98%82")
testEnc62 :: Test
testEnc62 = TestCase $ do
assertEqual "for (enc62 \"Hello, World!\")," (BSU.fromString "1wJfrzvdbtXUOlUjUf") (enc62 helloWorldBS)
assertEqual "for (enc62 \"Haskell\")," (BSU.fromString "1VJEByfMCK") (enc62 haskellBS)
assertEqual "for (enc62 \"😂\")," (BSU.fromString "4PCnnm") (enc62 emojiBS)
testDec62 :: Test
testDec62 = TestCase $ do
assertEqual "for (dec62 \"1wJfrzvdbtXUOlUjUf\")," helloWorldBS (dec62 $ BSU.fromString "1wJfrzvdbtXUOlUjUf")
assertEqual "for (dec62 \"1VJEByfMCK\")," haskellBS (dec62 $ BSU.fromString "1VJEByfMCK")
assertEqual "for (dec62 \"4PCnnm\")," emojiBS (dec62 $ BSU.fromString "4PCnnm")
testEnc45 :: Test
testEnc45 = TestCase $ do
assertEqual "for (enc45 \"Hello, World!\")," (BSU.fromString "%69 VDK2E:3404ESVDX0") (enc45 helloWorldBS)
assertEqual "for (enc45 \"Haskell\")," (BSU.fromString "Y69RQE: CI2") (enc45 haskellBS)
assertEqual "for (enc45 \"😂\")," (BSU.fromString "*IURCJ") (enc45 emojiBS)
testDec45 :: Test
testDec45 = TestCase $ do
assertEqual "for (dec45 \"%69 VDK2E:3404ESVDX0\")," helloWorldBS (dec45 $ BSU.fromString "%69 VDK2E:3404ESVDX0")
assertEqual "for (dec45 \"Y69RQE: CI2\")," haskellBS (dec45 $ BSU.fromString "Y69RQE: CI2")
assertEqual "for (dec45 \"*IURCJ\")," emojiBS (dec45 $ BSU.fromString "*IURCJ")
testEnc32 :: Test testEnc32 :: Test
testEnc32 = TestCase $ do testEnc32 = TestCase $ do
assertEqual "for (enc32 \"Hello, World!\")," "JBSWY3DPFQQFO33SNRSCC===" (enc32 "Hello, World!") assertEqual "for (enc32 \"Hello, World!\")," (BSU.fromString "JBSWY3DPFQQFO33SNRSCC===") (enc32 helloWorldBS)
assertEqual "for (enc32 \"Haskell\")," "JBQXG23FNRWA====" (enc32 "Haskell") assertEqual "for (enc32 \"Haskell\")," (BSU.fromString "JBQXG23FNRWA====") (enc32 haskellBS)
assertEqual "for (enc32 \"😂\")," "6CPZRAQ=" (enc32 "😂") assertEqual "for (enc32 \"😂\")," (BSU.fromString "6CPZRAQ=") (enc32 emojiBS)
testDec32 :: Test
testDec32 = TestCase $ do
assertEqual "for (dec32 \"JBSWY3DPFQQFO33SNRSCC===\")," helloWorldBS (dec32 $ BSU.fromString "JBSWY3DPFQQFO33SNRSCC===")
assertEqual "for (dec32 \"JBQXG23FNRWA====\")," haskellBS (dec32 $ BSU.fromString "JBQXG23FNRWA====")
-- assertEqual "for (dec32 \"AAEC\")," "\x00\x01\x02" (dec32 "AAEC")
assertEqual "for (dec32 \"6CPZRAQ=\")," emojiBS (dec32 $ BSU.fromString "6CPZRAQ=")
testEnc16 :: Test testEnc16 :: Test
testEnc16 = TestCase $ do testEnc16 = TestCase $ do
assertEqual "for (enc16 \"Hello, World!\")," "48656C6C6F2C20576F726C6421" (enc16 "Hello, World!") assertEqual "for (enc16 \"Hello, World!\")," (BSU.fromString "48656C6C6F2C20576F726C6421") (enc16 helloWorldBS)
assertEqual "for (enc16 \"Haskell\")," "4861736B656C6C" (enc16 "Haskell") assertEqual "for (enc16 \"Haskell\")," (BSU.fromString "4861736B656C6C") (enc16 haskellBS)
assertEqual "for (enc16 \"😂\")," "F09F9882" (enc16 "😂") assertEqual "for (enc16 \"😂\")," (BSU.fromString "F09F9882") (enc16 emojiBS)
testDec16 :: Test testDec16 :: Test
testDec16 = TestCase $ do testDec16 = TestCase $ do
assertEqual "for (dec16 \"48656C6C6F2C20576F726C6421\")," "Hello, World!" (dec16 "48656C6C6F2C20576F726C6421") assertEqual "for (dec16 \"48656C6C6F2C20576F726C6421\")," helloWorldBS (dec16 $ BSU.fromString "48656C6C6F2C20576F726C6421")
assertEqual "for (dec16 \"4861736B656C6C\")," "Haskell" (dec16 "4861736B656C6C") assertEqual "for (dec16 \"4861736B656C6C\")," haskellBS (dec16 $ BSU.fromString "4861736B656C6C")
assertEqual "for (dec16 \"F09F9882\")," "😂" (dec16 "F09F9882") assertEqual "for (dec16 \"F09F9882\")," emojiBS (dec16 $ BSU.fromString "F09F9882")
testEnc10 :: Test
testEnc10 = TestCase $ do
assertEqual "for (enc10 \"Hello, World!\")," (BSU.fromString "72 101 108 108 111 44 32 87 111 114 108 100 33") (enc10 helloWorldBS)
assertEqual "for (enc10 \"Haskell\")," (BSU.fromString "72 97 115 107 101 108 108") (enc10 haskellBS)
assertEqual "for (enc10 \"😂\")," (BSU.fromString "240 159 152 130") (enc10 emojiBS)
testDec10 :: Test
testDec10 = TestCase $ do
assertEqual "for (dec10 \"72 101 108 108 111 44 32 87 111 114 108 100 33\")," helloWorldBS (dec10 $ BSU.fromString "72 101 108 108 111 44 32 87 111 114 108 100 33")
assertEqual "for (dec10 \"72 97 115 107 101 108 108\")," haskellBS (dec10 $ BSU.fromString "72 97 115 107 101 108 108")
assertEqual "for (dec10 \"240 159 152 130\")," emojiBS (dec10 $ BSU.fromString "240 159 152 130")
testEnc8 :: Test testEnc8 :: Test
testEnc8 = TestCase $ do testEnc8 = TestCase $ do
assertEqual "for (enc8 \"Hello, World!\")," "110 145 154 154 157 54 40 127 157 162 154 144 41" (enc8 "Hello, World!") assertEqual "for (enc8 \"Hello, World!\")," (BSU.fromString "110 145 154 154 157 54 40 127 157 162 154 144 41") (enc8 helloWorldBS)
assertEqual "for (enc8 \"Haskell\")," "110 141 163 153 145 154 154" (enc8 "Haskell") assertEqual "for (enc8 \"Haskell\")," (BSU.fromString "110 141 163 153 145 154 154") (enc8 haskellBS)
assertEqual "for (enc8 \"😂\")," "360 237 230 202" (enc8 "😂") assertEqual "for (enc8 \"😂\")," (BSU.fromString "360 237 230 202") (enc8 emojiBS)
testDec8 :: Test testDec8 :: Test
testDec8 = TestCase $ do testDec8 = TestCase $ do
assertEqual "for (dec8 \"110 145 154 154 157 54 40 127 157 162 154 144 41\")," "Hello, World!" (dec8 "110 145 154 154 157 54 40 127 157 162 154 144 41") assertEqual "for (dec8 \"110 145 154 154 157 54 40 127 157 162 154 144 41\")," helloWorldBS (dec8 $ BSU.fromString "110 145 154 154 157 54 40 127 157 162 154 144 41")
assertEqual "for (dec8 \"110 141 163 153 145 154 154\")," "Haskell" (dec8 "110 141 163 153 145 154 154") assertEqual "for (dec8 \"110 141 163 153 145 154 154\")," haskellBS (dec8 $ BSU.fromString "110 141 163 153 145 154 154")
assertEqual "for (dec8 \"360 237 230 202\")," "😂" (dec8 "360 237 230 202") assertEqual "for (dec8 \"360 237 230 202\")," emojiBS (dec8 $ BSU.fromString "360 237 230 202")
testEnc2 :: Test testEnc2 :: Test
testEnc2 = TestCase $ do testEnc2 = TestCase $ do
assertEqual "for (enc2 \"Hello, World!\")," "01001000 01100101 01101100 01101100 01101111 00101100 00100000 01010111 01101111 01110010 01101100 01100100 00100001" (enc2 "Hello, World!") assertEqual "for (enc2 \"Hello, World!\")," (BSU.fromString "01001000 01100101 01101100 01101100 01101111 00101100 00100000 01010111 01101111 01110010 01101100 01100100 00100001") (enc2 helloWorldBS)
assertEqual "for (enc2 \"Haskell\")," "01001000 01100001 01110011 01101011 01100101 01101100 01101100" (enc2 "Haskell") assertEqual "for (enc2 \"Haskell\")," (BSU.fromString "01001000 01100001 01110011 01101011 01100101 01101100 01101100") (enc2 haskellBS)
assertEqual "for (enc2 \"😂\")," "11110000 10011111 10011000 10000010" (enc2 "😂") assertEqual "for (enc2 \"😂\")," (BSU.fromString "11110000 10011111 10011000 10000010") (enc2 emojiBS)
testDec2 :: Test testDec2 :: Test
testDec2 = TestCase $ do testDec2 = TestCase $ do
assertEqual "for (dec2 \"01001000 01100101 01101100 01101100 01101111 00101100 00100000 01010111 01101111 01110010 01101100 01100100 00100001\")," "Hello, World!" (dec2 "01001000 01100101 01101100 01101100 01101111 00101100 00100000 01010111 01101111 01110010 01101100 01100100 00100001") assertEqual "for (dec2 \"01001000 01100101 01101100 01101100 01101111 00101100 00100000 01010111 01101111 01110010 01101100 01100100 00100001\")," helloWorldBS (dec2 $ BSU.fromString "01001000 01100101 01101100 01101100 01101111 00101100 00100000 01010111 01101111 01110010 01101100 01100100 00100001")
assertEqual "for (dec2 \"01001000 01100001 01110011 01101011 01100101 01101100 01101100\")," "Haskell" (dec2 "01001000 01100001 01110011 01101011 01100101 01101100 01101100") assertEqual "for (dec2 \"01001000 01100001 01110011 01101011 01100101 01101100 01101100\")," haskellBS (dec2 $ BSU.fromString "01001000 01100001 01110011 01101011 01100101 01101100 01101100")
assertEqual "for (dec2 \"11110000 10011111 10011000 10000010\")," "😂" (dec2 "11110000 10011111 10011000 10000010") assertEqual "for (dec2 \"11110000 10011111 10011000 10000010\")," emojiBS (dec2 $ BSU.fromString "11110000 10011111 10011000 10000010")
testEncQp :: Test
testEncQp = TestCase $ do
assertEqual "for (encqp \"Hello, World!\")," (BSU.fromString "Hello,=20World!") (encqp helloWorldBS)
assertEqual "for (encqp \"QP works by using the equals sign = as an escape character. It also limits line length to 76, as some software has limits on line length.\")," (BSU.fromString "QP=20works=20by=20using=20the=20equals=20sign=20=3D=20as=20an=20escape=20=\r\ncharacter.=20It=20also=20limits=20line=20length=20to=2076,=20as=20some=20=\r\nsoftware=20has=20limits=20on=20line=20length.") (encqp $ BSU.fromString "QP works by using the equals sign = as an escape character. It also limits line length to 76, as some software has limits on line length.")
assertEqual "for (encqp \"😂\")," (BSU.fromString "=F0=9F=98=82") (encqp emojiBS)
testDecQp :: Test
testDecQp = TestCase $ do
assertEqual "for (decqp \"Hello,=20World!\")," helloWorldBS (decqp $ BSU.fromString "Hello,=20World!")
assertEqual "for (decqp \"QP=20works=20by=20using=20the=20equals=20sign=20=3D=20as=20an=20escape=20=\r\ncharacter.=20It=20also=20limits=20line=20length=20to=2076,=20as=20some=20=\r\nsoftware=20has=20limits=20on=20line=20length.\")," (BSU.fromString "QP works by using the equals sign = as an escape character. It also limits line length to 76, as some software has limits on line length.") (decqp $ BSU.fromString "QP=20works=20by=20using=20the=20equals=20sign=20=3D=20as=20an=20escape=20=\r\ncharacter.=20It=20also=20limits=20line=20length=20to=2076,=20as=20some=20=\r\nsoftware=20has=20limits=20on=20line=20length.")
assertEqual "for (decqp \"=F0=9F=98=82\")," emojiBS (decqp $ BSU.fromString "=F0=9F=98=82")
testEncUu :: Test
testEncUu = TestCase $ do
assertEqual "for (encuu \"Hello, World!\")," (BSU.fromString "-2&5L;&\\L(%=O<FQD(0") (encuu helloWorldBS)
assertEqual "for (encuu \"Haskell\")," (BSU.fromString "'2&%S:V5L; ") (encuu haskellBS)
assertEqual "for (encuu \"😂\")," (BSU.fromString "$\\)^8@@") (encuu emojiBS)
testDecUu :: Test
testDecUu = TestCase $ do
assertEqual "for (decuu \"-2&5L;&\\L(%=O<FQD(0\")," helloWorldBS (decuu $ BSU.fromString "-2&5L;&\\L(%=O<FQD(0")
assertEqual "for (decuu \"'2&%S:V5L;\")," haskellBS (decuu $ BSU.fromString "'2&%S:V5L; ")
assertEqual "for (decuu \"$\\)^8@@\")," (BSU.fromString "😂") (decuu $ BSU.fromString "$\\)^8@@")
testEncXx :: Test
testEncXx = TestCase $ do
assertEqual "for (encxx \"Hello, World!\")," (BSU.fromString "G4JgP4wg63RjQalY6E") (encxx helloWorldBS)
assertEqual "for (encxx \"foobar\")," (BSU.fromString "NaxjMa3m") (encxx $ BSU.fromString "foobar")
assertEqual "for (encxx \"😂\")," (BSU.fromString "w7yMUU") (encxx emojiBS)
testDecXx :: Test
testDecXx = TestCase $ do
assertEqual "for (decxx \"G4JgP4wg63RjQalY6E\")," helloWorldBS (decxx $ BSU.fromString "G4JgP4wg63RjQalY6E")
assertEqual "for (decxx \"NaxjMa3m\")," (BSU.fromString "foobar") (decxx $ BSU.fromString "NaxjMa3m")
assertEqual "for (decxx \"w7yMUU\")," (BSU.fromString "😂") (decxx $ BSU.fromString "w7yMUU")
testEncYenc :: Test
testEncYenc = TestCase $ do
assertEqual "for (ency \"Hello, World!\")," (B.pack [114, 143, 150, 150, 153, 86, 74, 129, 153, 156, 150, 142, 75]) (ency helloWorldBS)
assertEqual "for (ency \"😂\")," (B.pack [26, 201, 194, 172] ) (ency emojiBS)
testDecYenc:: Test
testDecYenc= TestCase $ do
assertEqual "for (decy \"r<8f><96><96><99>VJ<81><99><9c><96><8e>K\")," helloWorldBS (decy $ B.pack [114, 143, 150, 150, 153, 86, 74, 129, 153, 156, 150, 142, 75] )
assertEqual "for (decy \"^Z<c9>¬\")," (BSU.fromString "😂") (decy $ B.pack [26, 201, 194, 172])
testRotate :: Test
testRotate = TestCase $ do
assertEqual "for (rotate 13 \"Hello, World!\")," (BSU.fromString "Uryyb, Jbeyq!") (rotate 13 (BSU.fromString "Hello, World!"))
assertEqual "for (rotate 8 \"Hello, World!\")," (BSU.fromString "Pmttw, Ewztl!") (rotate 8 (BSU.fromString "Hello, World!"))
assertEqual "for (rotate 2 \"😂\")," (BSU.fromString "😂") (rotate 2 (BSU.fromString "😂"))
tests :: Test tests :: Test
tests = TestList [TestLabel "Test enc64" testEnc64, tests = TestList [TestLabel "Test enc91" testEnc91,
TestLabel "Test dec91" testDec91,
TestLabel "Test enc85" testEnc85,
TestLabel "Test dec85" testDec85,
TestLabel "Test enc64" testEnc64,
TestLabel "Test dec64" testDec64, TestLabel "Test dec64" testDec64,
TestLabel "Test enc64url" testEnc64Url,
TestLabel "Test dec64url" testDec64Url,
TestLabel "Test url" testEncUrl,
TestLabel "Test url" testDecUrl,
TestLabel "Test enc62" testEnc62,
TestLabel "Test dec62" testDec62,
TestLabel "Test enc45" testEnc45,
TestLabel "Test dec45" testDec45,
TestLabel "Test enc32" testEnc32, TestLabel "Test enc32" testEnc32,
TestLabel "Test dec32" testDec32, TestLabel "Test dec32" testDec32,
TestLabel "Test enc16" testEnc16, TestLabel "Test enc16" testEnc16,
TestLabel "Test dec16" testDec16, TestLabel "Test dec16" testDec16,
TestLabel "Test enc10" testEnc10,
TestLabel "Test dec10" testDec10,
TestLabel "Test enc8 " testEnc8 , TestLabel "Test enc8 " testEnc8 ,
TestLabel "Test dec8 " testDec8 , TestLabel "Test dec8 " testDec8 ,
TestLabel "Test dec2 " testDec2 , TestLabel "Test dec2 " testDec2 ,
TestLabel "Test enc2 " testEnc2 ] TestLabel "Test enc2 " testEnc2 ,
TestLabel "Test decqp" testDecQp,
TestLabel "Test encqp" testEncQp,
TestLabel "Test decuu" testDecUu,
TestLabel "Test encuu" testEncUu,
TestLabel "Test decuu" testDecXx,
TestLabel "Test encuu" testEncXx,
TestLabel "Test ency" testEncYenc,
TestLabel "Test rot" testRotate]
-- main :: IO Counts -- main :: IO Counts