Compare commits
13 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
56f75e2783 | |
|
|
85b57ef9aa | |
|
|
e39ac84573 | |
|
|
3bc2062bf3 | |
|
|
6213a4a221 | |
|
|
f06925d9b8 | |
|
|
b60acf2008 | |
|
|
3bd5530544 | |
|
|
f5d35aa555 | |
|
|
e0d97a4084 | |
|
|
8664170b0d | |
|
|
61313cd558 | |
|
|
63a0fd3c05 |
|
|
@ -1,5 +1,13 @@
|
||||||
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
|
0.4.4.0 -- 2024-06-09
|
||||||
|
|
||||||
Added tests for every encode function included
|
Added tests for every encode function included
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
.DEFAULT_GOAL := build
|
||||||
|
|
||||||
|
PACKAGE_NAME := based
|
||||||
|
CABAL := cabal
|
||||||
|
BUILD_FLAGS := --builddir=dist-newstyle
|
||||||
|
BUILD_DEV_FLAGS := --enable-tests --enable-benchmarks
|
||||||
|
# STATIC_FLAGS := --ghc-options="-optl-static"
|
||||||
|
STATIC_FLAGS := --enable-executable-static -O2
|
||||||
|
STRIP := strip
|
||||||
|
STRIP_FLAGS := --strip-all
|
||||||
|
INSTALL_DIR := /usr/local/bin
|
||||||
|
INSTALL_FLAGS := --overwrite-policy=always
|
||||||
|
BIN_NAME := $(PACKAGE_NAME)
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
|
||||||
|
build:
|
||||||
|
$(CABAL) v2-build $(BUILD_FLAGS)
|
||||||
|
|
||||||
|
static-build:
|
||||||
|
$(CABAL) v2-build $(BUILD_FLAGS) $(STATIC_FLAGS)
|
||||||
|
|
||||||
|
dev-build:
|
||||||
|
$(CABAL) v2-build $(BUILD_FLAGS) $(BUILD_DEV_FLAGS)
|
||||||
|
|
||||||
|
strip:
|
||||||
|
$(STRIP) $(STRIP_FLAGS) $(realpath $(which $(PACKAGE_NAME)))
|
||||||
|
|
||||||
|
user-install:
|
||||||
|
$(CABAL) v2-install $(BUILD_FLAGS) $(INSTALL_FLAGS)
|
||||||
|
$(STRIP) $(STRIP_FLAGS) $(realpath $(which $(PACKAGE_NAME)))
|
||||||
|
|
||||||
|
install: user-install
|
||||||
|
install -m 755 $(shell cabal v2-exec which $(BIN_NAME)) $(INSTALL_DIR)/$(BIN_NAME)
|
||||||
|
$(STRIP) $(STRIP_FLAGS) $(realpath $(which $(PACKAGE_NAME)))
|
||||||
|
echo "$(BIN_NAME) installed to $(INSTALL_DIR)"
|
||||||
|
|
||||||
|
static-install: static-build user-install
|
||||||
|
install -m 755 $(shell cabal v2-exec which $(BIN_NAME)) $(INSTALL_DIR)/$(BIN_NAME)
|
||||||
|
$(STRIP) $(STRIP_FLAGS) $(realpath $(which $(PACKAGE_NAME)))
|
||||||
|
echo "$(BIN_NAME) installed to $(INSTALL_DIR)"
|
||||||
|
|
||||||
|
test:
|
||||||
|
$(CABAL) v2-test $(BUILD_FLAGS)
|
||||||
|
|
||||||
|
clean-artifacts:
|
||||||
|
$(CABAL) v2-clean
|
||||||
|
|
||||||
|
clean: clean-artifacts
|
||||||
|
rm -f $(INSTALL_DIR)/$(BIN_NAME) \
|
||||||
|
&& echo "$(BIN_NAME) removed from $(INSTALL_DIR)" \
|
||||||
|
|| echo "$(BIN_NAME) cannot be found in $(INSTALL_DIR)"
|
||||||
|
|
||||||
70
app/Main.hs
70
app/Main.hs
|
|
@ -5,8 +5,7 @@
|
||||||
module Main where
|
module Main where
|
||||||
import System.Console.CmdArgs
|
import System.Console.CmdArgs
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import qualified Data.ByteString.Char8 as BC
|
import Encoding.Unary (encunary, decunary)
|
||||||
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)
|
||||||
|
|
@ -23,7 +22,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 {
|
||||||
|
|
@ -40,11 +43,15 @@ data Based = Decode {
|
||||||
b10 :: Bool,
|
b10 :: Bool,
|
||||||
b8 :: Bool,
|
b8 :: Bool,
|
||||||
b2 :: Bool,
|
b2 :: Bool,
|
||||||
|
unary :: Bool,
|
||||||
qp :: Bool,
|
qp :: Bool,
|
||||||
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 {
|
||||||
|
|
@ -61,49 +68,18 @@ data Based = Decode {
|
||||||
b10 :: Bool,
|
b10 :: Bool,
|
||||||
b8 :: Bool,
|
b8 :: Bool,
|
||||||
b2 :: Bool,
|
b2 :: Bool,
|
||||||
|
unary :: Bool,
|
||||||
qp :: Bool,
|
qp :: Bool,
|
||||||
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)
|
||||||
|
|
||||||
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 "\nTrying base91:\n" `BC.append` dec91 input else BC.empty
|
|
||||||
base85Result = if isBase85 then BC.pack "\nTrying base85:\n" `BC.append` dec85 input else BC.empty
|
|
||||||
base64Result = if isBase64 then BC.pack "\nTrying base64:\n" `BC.append` dec64 input else BC.empty
|
|
||||||
base58Result = if isBase58 then BC.pack "\nTrying base58:\n" `BC.append` dec58 input else BC.empty
|
|
||||||
base32Result = if isBase64 then BC.pack "\nTrying base32:\n" `BC.append` dec32 input else BC.empty
|
|
||||||
base16Result = if isBase16 then BC.pack "\nTrying base16:\n" `BC.append` dec16 input else BC.empty
|
|
||||||
base10Result = if isBase10 then BC.pack "\nTrying base10:\n" `BC.append` dec10 input else BC.empty
|
|
||||||
base2Result = if isBase2 then BC.pack "\nTrying base2:\n" `BC.append` dec2 input else BC.empty
|
|
||||||
base8Result = if isBase8 then BC.pack "\nTrying base8:\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]
|
|
||||||
|
|
||||||
|
|
||||||
optionHandler :: Based -> B.ByteString -> B.ByteString
|
optionHandler :: Based -> B.ByteString -> B.ByteString
|
||||||
optionHandler Decode{b91=True} = dec91
|
optionHandler Decode{b91=True} = dec91
|
||||||
|
|
@ -132,6 +108,8 @@ optionHandler Decode{b8=True} = dec8
|
||||||
optionHandler Encode{b8=True} = enc8
|
optionHandler Encode{b8=True} = enc8
|
||||||
optionHandler Decode{b2=True} = dec2
|
optionHandler Decode{b2=True} = dec2
|
||||||
optionHandler Encode{b2=True} = enc2
|
optionHandler Encode{b2=True} = enc2
|
||||||
|
optionHandler Decode{unary=True} = decunary
|
||||||
|
optionHandler Encode{unary=True} = encunary
|
||||||
optionHandler Decode{qp=True} = decqp
|
optionHandler Decode{qp=True} = decqp
|
||||||
optionHandler Encode{qp=True} = encqp
|
optionHandler Encode{qp=True} = encqp
|
||||||
optionHandler Encode{uu=True} = encuu
|
optionHandler Encode{uu=True} = encuu
|
||||||
|
|
@ -140,8 +118,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
|
||||||
|
|
@ -159,11 +143,15 @@ decodeMode = Decode {
|
||||||
b10 = def &= help "decode decimal",
|
b10 = def &= help "decode decimal",
|
||||||
b8 = def &= help "decode octal",
|
b8 = def &= help "decode octal",
|
||||||
b2 = def &= help "decode base2",
|
b2 = def &= help "decode base2",
|
||||||
|
unary = def &= help "decode unary (8 bit) a.k.a. Chuck Norris",
|
||||||
qp = def &= help "decode quoted-printable",
|
qp = def &= help "decode quoted-printable",
|
||||||
uu = def &= help "decode UnixToUnix",
|
uu = def &= help "decode UnixToUnix",
|
||||||
xx = def &= help "decode xx, without padding",
|
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
|
||||||
|
|
||||||
|
|
@ -182,11 +170,15 @@ encodeMode = Encode {
|
||||||
b10 = def &= help "encode decimal",
|
b10 = def &= help "encode decimal",
|
||||||
b8 = def &= help "encode octal",
|
b8 = def &= help "encode octal",
|
||||||
b2 = def &= help "encode base2",
|
b2 = def &= help "encode base2",
|
||||||
|
unary = def &= help "encode unary (8 bit) a.k.a. Chuck Norris",
|
||||||
qp = def &= help "encode quoted-printable",
|
qp = def &= help "encode quoted-printable",
|
||||||
uu = def &= help "encode UnixToUnix",
|
uu = def &= help "encode UnixToUnix",
|
||||||
xx = def &= help "encode xx, without padding",
|
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()
|
||||||
|
|
|
||||||
13
based.cabal
13
based.cabal
|
|
@ -1,6 +1,6 @@
|
||||||
cabal-version: 2.4
|
cabal-version: 2.4
|
||||||
name: based
|
name: based
|
||||||
version: 0.4.4.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
|
||||||
|
|
@ -8,6 +8,7 @@ author: Stefan Friese
|
||||||
library
|
library
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
|
Encoding.Unary
|
||||||
Encoding.Base2
|
Encoding.Base2
|
||||||
Encoding.Base8
|
Encoding.Base8
|
||||||
Encoding.Base10
|
Encoding.Base10
|
||||||
|
|
@ -25,6 +26,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:
|
||||||
|
|
@ -42,7 +47,11 @@ library
|
||||||
haskoin-core,
|
haskoin-core,
|
||||||
text,
|
text,
|
||||||
primitive,
|
primitive,
|
||||||
base64-bytestring
|
regex-tdfa,
|
||||||
|
base64-bytestring,
|
||||||
|
containers,
|
||||||
|
split,
|
||||||
|
MorseCode
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
||||||
executable based
|
executable based
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -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]
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
23
test/Main.hs
23
test/Main.hs
|
|
@ -17,6 +17,8 @@ import Encoding.Base2 (enc2, dec2)
|
||||||
import Encoding.QuotedPrintable (encqp, decqp)
|
import Encoding.QuotedPrintable (encqp, decqp)
|
||||||
import Encoding.UnixToUnix (encuu, decuu)
|
import Encoding.UnixToUnix (encuu, decuu)
|
||||||
import Encoding.Xx (encxx, decxx)
|
import Encoding.Xx (encxx, decxx)
|
||||||
|
import Encoding.Yenc (ency, decy)
|
||||||
|
import Encoding.Rotate (rotate)
|
||||||
import System.Exit (exitFailure, exitSuccess)
|
import System.Exit (exitFailure, exitSuccess)
|
||||||
|
|
||||||
helloWorldBS :: B.ByteString
|
helloWorldBS :: B.ByteString
|
||||||
|
|
@ -218,6 +220,23 @@ testDecXx = TestCase $ do
|
||||||
assertEqual "for (decxx \"NaxjMa3m\")," (BSU.fromString "foobar") (decxx $ BSU.fromString "NaxjMa3m")
|
assertEqual "for (decxx \"NaxjMa3m\")," (BSU.fromString "foobar") (decxx $ BSU.fromString "NaxjMa3m")
|
||||||
assertEqual "for (decxx \"w7yMUU\")," (BSU.fromString "😂") (decxx $ BSU.fromString "w7yMUU")
|
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 enc91" testEnc91,
|
tests = TestList [TestLabel "Test enc91" testEnc91,
|
||||||
TestLabel "Test dec91" testDec91,
|
TestLabel "Test dec91" testDec91,
|
||||||
|
|
@ -248,7 +267,9 @@ tests = TestList [TestLabel "Test enc91" testEnc91,
|
||||||
TestLabel "Test decuu" testDecUu,
|
TestLabel "Test decuu" testDecUu,
|
||||||
TestLabel "Test encuu" testEncUu,
|
TestLabel "Test encuu" testEncUu,
|
||||||
TestLabel "Test decuu" testDecXx,
|
TestLabel "Test decuu" testDecXx,
|
||||||
TestLabel "Test encuu" testEncXx]
|
TestLabel "Test encuu" testEncXx,
|
||||||
|
TestLabel "Test ency" testEncYenc,
|
||||||
|
TestLabel "Test rot" testRotate]
|
||||||
|
|
||||||
|
|
||||||
-- main :: IO Counts
|
-- main :: IO Counts
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue