diff --git a/CHANGELOG.md b/CHANGELOG.md index 222de44..90a0e90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ Revision history for based +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 Added rotate function to encode and decode diff --git a/README.md b/README.md index 03dea68..b995030 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # 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 ```sh @@ -8,11 +9,13 @@ cabal v2-build --enable-executable-static -O2 strip --strip-all based ``` -Do not forget to set `$LD_LIBRARY_PATH` to the directory of your static libs. +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 * If you want to compile your own build, link it dynamically via + ```sh git clone https://git.stefan.works/whx/based.git cd based/ @@ -20,6 +23,11 @@ cabal install 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 * Pipe via stdin to transcode @@ -42,25 +50,22 @@ Run `cabal test` ## What is Transcoded? The following are the supported encodings + * Base91 * Base85 * Base64 * Base64url -* URI Encoding +* URL Encoding * Base62 * Base58 +* Base45 * Base32 +* Base16 +* Base10 +* Base2 * Quoted-Printable * UU Encoding * XX Encoding * yEncoding * Rotate (1..26) -* Unicode to hex and vice versa -* Unicode to dec and vice versa -* Unicode to oct and vice versa -* Unicode to bin and vice versa -* ~~Char to Hex and vice versa~~ -* ~~Decimal to Hex and vice versa~~ -* ~~Oktal to Hex and vice versa~~ -* ~~Binary to Hex and vice versa~~ diff --git a/app/Main.hs b/app/Main.hs index 740f357..26347fe 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -4,9 +4,6 @@ module Main where import System.Console.CmdArgs ---import Control.Arrow ---import Data.ByteString.UTF8 as BSU -- from utf8-string ---import qualified Data.ByteString.Char8 as C import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC import Text.Regex.TDFA @@ -72,71 +69,6 @@ data Based = Decode { } deriving(Show, Data, Typeable) ----- helper functions - ----- convertToByteString :: String -> Either String C.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 - base91Regex = "^[!-~]*$" base85Regex = "^[0-9A-Za-z!#$%&()*+,-;<=>?@^_`{|}~]+$" base64Regex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$" @@ -172,18 +104,6 @@ solveEnc input = 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] --- -- --- -- | 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 :: Based -> B.ByteString -> B.ByteString optionHandler Decode{b91=True} = dec91 @@ -241,7 +161,7 @@ decodeMode = Decode { b2 = def &= help "decode base2", qp = def &= help "decode quoted-printable", uu = def &= help "decode UnixToUnix", - xx = def &= help "decode xx", + xx = def &= help "decode xx, without padding", yenc = def &= help "decode yEncode", rot = def &= help "rotate characters by n positions", solve = def &= help "solve encoding" @@ -264,64 +184,13 @@ encodeMode = Encode { b2 = def &= help "encode base2", qp = def &= help "encode quoted-printable", uu = def &= help "encode UnixToUnix", - xx = def &= help "encode xx", + xx = def &= help "encode xx, without padding", yenc = def &= help "encode yEncode", rot = def &= help "rotate characters by n positions" } &= help "Encode chosen base" ---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 :: IO() 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 - --- #!/usr/bin/env runhaskell - --- {-# LANGUAGE DeriveDataTypeable #-} - --- module Main where - --- import System.Console.CmdArgs --- import qualified Data.ByteString as B --- import qualified Data.ByteString.Base64 as B64 --- import qualified Data.ByteString.Char8 as BC - --- data Based = Decode { b64 :: Bool } --- | Encode { b64 :: Bool } --- deriving (Show, Data, Typeable) - --- -- Function to decode from Base64 --- dec64 :: B.ByteString -> B.ByteString --- dec64 input = case B64.decode input of --- Right byteString -> byteString --- Left _ -> BC.pack "Error: Invalid Base64 input" - --- -- Function to encode to Base64 --- enc64 :: B.ByteString -> B.ByteString --- enc64 = B64.encode - --- Handle the option to encode or decode --- optionHandler :: Based -> B.ByteString -> B.ByteString --- optionHandler Decode { b64 = True } = dec64 --- optionHandler Encode { b64 = True } = enc64 - --- decodeMode :: Based --- decodeMode = Decode { b64 = def &= help "decode base64" } --- &= help "Decode chosen base" &= auto - --- encodeMode :: Based --- encodeMode = Encode { b64 = def &= help "encode base64" } --- &= help "Encode chosen base" - --- main :: IO () --- main = do --- -- Read command line arguments --- args <- cmdArgs (modes [decodeMode, encodeMode] &= help "Based.\nTo see every parameter of every mode use --help=all" &= program "based" &= summary "based v0.4") --- -- Read input from stdin --- input <- B.getContents --- -- Process the input according to the command line arguments --- B.putStr $ optionHandler args input - diff --git a/based.cabal b/based.cabal index 2531b19..7e3917b 100644 --- a/based.cabal +++ b/based.cabal @@ -1,6 +1,6 @@ cabal-version: 2.4 name: based -version: 0.4.3.0 +version: 0.4.4.0 license-file: LICENSE extra-source-files: CHANGELOG.md author: Stefan Friese