Skip to content

Commit c37f822

Browse files
committed
Refactored multiple encodings for using add_map
1 parent 106ebfa commit c37f822

9 files changed

Lines changed: 75 additions & 338 deletions

File tree

codext/crypto/barbie.py

Lines changed: 14 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# -*- coding: UTF-8 -*-
22
"""Barbie typewriter Codec - barbie content encoding.
33
4-
While Barbie typewriter is more a cipher, its very limited key size of 2 bits
5-
makes it easy to turn into four variants of the same encoding.
4+
While Barbie typewriter is more a cipher, its very limited key size of 2 bits makes it easy to turn into four variants
5+
of the same encoding.
66
77
This codec:
88
- en/decodes strings from str to str
@@ -15,7 +15,6 @@
1515
from ..__common__ import *
1616

1717

18-
REPLACE_CHAR = "?"
1918
STD = [
2019
"abcdefghijklmnopqrstuvABCDEFGHIJKLMNOPQRSTUVWXYZ0123456 \n\t",
2120
"icolapxstvybjeruknfhqg>FAUTCYOLVJDZINQKSEHG<.1PB5234067 \n\t",
@@ -30,70 +29,15 @@
3029
"+ b ; ¢ - ¨ § £ ( m v / W j @ # ? M B € & . % ! ^ \" * , 2 ) E : \' = _",
3130
"% c ¢ + ¨ § £ € * j g ^ . v ? @ / Z F = \" N : & ! m # W 3 ( T , _ \' )",
3231
]
33-
34-
35-
class BarbieError(ValueError):
36-
pass
37-
38-
39-
class BarbieDecodeError(BarbieError):
40-
pass
41-
42-
43-
class BarbieEncodeError(BarbieError):
44-
pass
45-
46-
47-
def barbie_encode(code):
48-
def encode(text, errors="strict"):
49-
std0, stdn = [c for c in STD[0]], [c for c in STD[code]]
50-
spec0, specn = SPEC[0].split(), SPEC[code].split()
51-
mapping = {d: e for d, e in zip(std0 + spec0, stdn + specn)}
52-
r = ""
53-
for i, c in enumerate(ensure_str(text)):
54-
try:
55-
r += mapping[c]
56-
except KeyError:
57-
if errors == "strict":
58-
raise BarbieEncodeError("'barbie' codec can't encode"
59-
" character '{}' in position {}"
60-
.format(c, i))
61-
elif errors == "replace":
62-
r += REPLACE_CHAR
63-
elif errors == "ignore":
64-
continue
65-
else:
66-
raise ValueError("Unsupported error handling {}"
67-
.format(errors))
68-
return r, len(text)
69-
return encode
70-
71-
72-
def barbie_decode(code):
73-
def decode(text, errors="strict"):
74-
std0, stdn = [c for c in STD[0]], [c for c in STD[code]]
75-
spec0, specn = SPEC[0].split(), SPEC[code].split()
76-
mapping = {e: d for d, e in zip(std0 + spec0, stdn + specn)}
77-
r = ""
78-
for i, c in enumerate(ensure_str(text)):
79-
try:
80-
r += mapping[c]
81-
except KeyError:
82-
if errors == "strict":
83-
raise BarbieDecodeError("'barbie' codec can't decode"
84-
" character '{}' in position {}"
85-
.format(c, i))
86-
elif errors == "replace":
87-
r += REPLACE_CHAR
88-
elif errors == "ignore":
89-
continue
90-
else:
91-
raise ValueError("Unsupported error handling {}"
92-
.format(errors))
93-
return r, len(text)
94-
return decode
95-
96-
97-
# note: the integer behind "barbie" is captured for sending to the
98-
# parametrizable encode and decode functions "barbie_**code"
99-
add("barbie", barbie_encode, barbie_decode, r"barbie[-_]?([1-4])$")
32+
ENCMAP = []
33+
for i in range(4):
34+
encmap = {}
35+
for j, c in enumerate(STD[0]):
36+
encmap[c] = STD[i+1][j]
37+
spec = SPEC[i+1].split()
38+
for j, c in enumerate(SPEC[0].split()):
39+
encmap[c] = spec[j]
40+
ENCMAP.append(encmap)
41+
42+
43+
add_map("barbie", ENCMAP, pattern=r"^barbie[-_]?([1-4])$")

codext/languages/braille.py

Lines changed: 14 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -10,77 +10,19 @@
1010
from ..__common__ import *
1111

1212

13-
if PY3:
14-
ENCMAP = {
15-
# digits
16-
'0': '⠴', '1': '⠂', '2': '⠆', '3': '⠒', '4': '⠲', '5': '⠢', '6': '⠖',
17-
'7': '⠶', '8': '⠦', '9': '⠔',
18-
# letters
19-
'a': '⠁', 'b': '⠃', 'c': '⠉', 'd': '⠙', 'e': '⠑', 'f': '⠋', 'g': '⠛',
20-
'h': '⠓', 'i': '⠊', 'j': '⠚', 'k': '⠅', 'l': '⠇', 'm': '⠍', 'n': '⠝',
21-
'o': '⠕', 'p': '⠏', 'q': '⠟', 'r': '⠗', 's': '⠎', 't': '⠞', 'u': '⠥',
22-
'v': '⠧', 'w': '⠺', 'x': '⠭', 'y': '⠽', 'z': '⠵',
23-
# punctuation
24-
' ': '⠀', '!': '⠮', '"': '⠐', '#': '⠼', '$': '⠫', '%': '⠩', '&': '⠯',
25-
':': '⠱', ';': '⠰', '<': '⠣', '=': '⠿', '>': '⠜', '?': '⠹', '@': '⠈',
26-
"'": '⠄', '(': '⠷', ')': '⠾', '*': '⠡', '+': '⠬', ',': '⠠', '-': '⠤',
27-
'.': '⠨', '/': '⠌', '[': '⠪', '\\': '⠳', ']': '⠻', '^': '⠘',
28-
'_': '⠸',
29-
}
30-
DECMAP = {v: k for k, v in ENCMAP.items()}
31-
REPLACE_CHAR = "?"
32-
33-
34-
class BrailleError(ValueError):
35-
pass
36-
37-
38-
class BrailleDecodeError(BrailleError):
39-
pass
40-
13+
ENCMAP = {
14+
# digits
15+
'0': '⠴', '1': '⠂', '2': '⠆', '3': '⠒', '4': '⠲', '5': '⠢', '6': '⠖', '7': '⠶', '8': '⠦', '9': '⠔',
16+
# letters
17+
'a': '⠁', 'b': '⠃', 'c': '⠉', 'd': '⠙', 'e': '⠑', 'f': '⠋', 'g': '⠛', 'h': '⠓', 'i': '⠊', 'j': '⠚', 'k': '⠅',
18+
'l': '⠇', 'm': '⠍', 'n': '⠝', 'o': '⠕', 'p': '⠏', 'q': '⠟', 'r': '⠗', 's': '⠎', 't': '⠞', 'u': '⠥', 'v': '⠧',
19+
'w': '⠺', 'x': '⠭', 'y': '⠽', 'z': '⠵',
20+
# punctuation
21+
' ': '⠀', '!': '⠮', '"': '⠐', '#': '⠼', '$': '⠫', '%': '⠩', '&': '⠯', ':': '⠱', ';': '⠰', '<': '⠣', '=': '⠿',
22+
'>': '⠜', '?': '⠹', '@': '⠈', "'": '⠄', '(': '⠷', ')': '⠾', '*': '⠡', '+': '⠬', ',': '⠠', '-': '⠤', '.': '⠨',
23+
'/': '⠌', '[': '⠪', '\\': '⠳', ']': '⠻', '^': '⠘', '_': '⠸',
24+
}
4125

42-
class BrailleEncodeError(BrailleError):
43-
pass
4426

45-
46-
def braille_encode(text, errors="strict"):
47-
r = ""
48-
for i, c in enumerate(ensure_str(text)):
49-
try:
50-
r += ENCMAP[c]
51-
except KeyError:
52-
if errors == "strict":
53-
raise BrailleEncodeError("'braille' codec can't encode "
54-
"character '{}' in position {}"
55-
.format(c, i))
56-
elif errors == "replace":
57-
r += REPLACE_CHAR
58-
elif errors == "ignore":
59-
continue
60-
else:
61-
raise ValueError("Unsupported error handling {}"
62-
.format(errors))
63-
return r, len(text)
64-
65-
66-
def braille_decode(text, errors="strict"):
67-
r = ""
68-
for i, c in enumerate(ensure_str(text)):
69-
try:
70-
r += DECMAP[c]
71-
except KeyError:
72-
if errors == "strict":
73-
raise BrailleDecodeError("'braille' codec can't decode "
74-
"character '{}' in position {}"
75-
.format(c, i))
76-
elif errors == "replace":
77-
r += REPLACE_CHAR
78-
elif errors == "ignore":
79-
continue
80-
else:
81-
raise ValueError("Unsupported error handling {}"
82-
.format(errors))
83-
return r, len(text)
84-
85-
86-
add("braille", braille_encode, braille_decode)
27+
if PY3:
28+
add_map("braille", ENCMAP)

codext/languages/morse.py

Lines changed: 9 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -12,72 +12,19 @@
1212

1313
ENCMAP = {
1414
# letters
15-
'a': ".-", 'b': "-...", 'c': "-.-.", 'd': "-..", 'e': ".", 'f': "..-.",
16-
'g': "--.", 'h': "....", 'i': "..", 'j': ".---", 'k': "-.-", 'l': ".-..",
17-
'm': "--", 'n': "-.", 'o': "---", 'p': ".--.", 'q': "--.-", 'r': ".-.",
18-
's': "...", 't': "-", 'u': "..-", 'v': "...-", 'w': ".--", 'x': "-..-",
19-
'y': "-.--", 'z': "--..",
15+
'a': ".-", 'b': "-...", 'c': "-.-.", 'd': "-..", 'e': ".", 'f': "..-.", 'g': "--.", 'h': "....", 'i': "..",
16+
'j': ".---", 'k': "-.-", 'l': ".-..", 'm': "--", 'n': "-.", 'o': "---", 'p': ".--.", 'q': "--.-", 'r': ".-.",
17+
's': "...", 't': "-", 'u': "..-", 'v': "...-", 'w': ".--", 'x': "-..-", 'y': "-.--", 'z': "--..",
2018
# digits
21-
'1': ".----", '2': "..---", '3': "...--", '4': "....-", '5': ".....",
22-
'6': "-....", '7': "--...", '8': "---..", '9': "----.", '0': "-----",
19+
'1': ".----", '2': "..---", '3': "...--", '4': "....-", '5': ".....", '6': "-....", '7': "--...", '8': "---..",
20+
'9': "----.", '0': "-----",
2321
# punctuation
24-
',': "--..--", '.': ".-.-.-", ':' : "---...", '?': "..--..", '/': "-..-.",
25-
'-': "-....-", '=' : "-...-", '(': "-.--.", ')': "-.--.-", '@' : ".--.-.",
26-
'\'': ".----.", '_': "..--.-", '!': "-.-.--", '&': ".-...", '"': ".-..-.",
27-
';': "-.-.-.", '$': "...-..-",
22+
',': "--..--", '.': ".-.-.-", ':' : "---...", '?': "..--..", '/': "-..-.", '-': "-....-", '=' : "-...-",
23+
'(': "-.--.", ')': "-.--.-", '@' : ".--.-.", '\'': ".----.", '_': "..--.-", '!': "-.-.--", '&': ".-...",
24+
'"': ".-..-.", ';': "-.-.-.", '$': "...-..-",
2825
# word separator
2926
' ' : "/",
3027
}
31-
DECMAP = {v: k for k, v in ENCMAP.items()}
32-
REPLACE_CHAR = "#"
3328

3429

35-
class MorseError(ValueError):
36-
pass
37-
38-
39-
class MorseDecodeError(MorseError):
40-
pass
41-
42-
43-
class MorseEncodeError(MorseError):
44-
pass
45-
46-
47-
def morse_encode(text, errors="strict"):
48-
r = ""
49-
for i, c in enumerate(ensure_str(text)):
50-
try:
51-
r += ENCMAP[c] + " "
52-
except KeyError:
53-
if errors == "strict":
54-
raise MorseEncodeError("'morse' codec can't encode character "
55-
"'{}' in position {}".format(c, i))
56-
elif errors == "replace":
57-
r += REPLACE_CHAR + " "
58-
elif errors == "ignore":
59-
continue
60-
else:
61-
raise ValueError("Unsupported error handling {}".format(errors))
62-
return r[:-1], len(text)
63-
64-
65-
def morse_decode(text, errors="strict"):
66-
r = ""
67-
for i, c in enumerate(ensure_str(text).split()):
68-
try:
69-
r += DECMAP[c]
70-
except KeyError:
71-
if errors == "strict":
72-
raise MorseDecodeError("'morse' codec can't decode character "
73-
"'{}' in position {}".format(c, i))
74-
elif errors == "replace":
75-
r += REPLACE_CHAR
76-
elif errors == "ignore":
77-
continue
78-
else:
79-
raise ValueError("Unsupported error handling {}".format(errors))
80-
return r, len(text)
81-
82-
83-
add("morse", morse_encode, morse_decode)
30+
add_map("morse", ENCMAP, "#", " ", pattern=r"^morse([-_]?.{3})?$")

codext/others/dna.py

Lines changed: 7 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
# -*- coding: UTF-8 -*-
22
"""DNA Codec - dna content encoding.
33
4-
This implements the 8 methods of ATGC nucleotides following the rule of
5-
complementary pairing, according the literature about coding and computing of
6-
DNA sequences.
4+
This implements the 8 methods of ATGC nucleotides following the rule of complementary pairing, according the literature4
5+
about coding and computing of DNA sequences.
76
87
This codec:
98
- en/decodes strings from str to str
@@ -14,63 +13,15 @@
1413
from ..__common__ import *
1514

1615

17-
ENCMAP = {
16+
SEQUENCES = {
1817
'00': "AAGCGCTT",
1918
'11': "TTCGCGAA",
2019
'01': "GCAATTGC",
2120
'10': "CGTTAACG",
2221
}
23-
DECMAP = [{v[i]: k for k, v in ENCMAP.items()} for i in range(8)]
24-
REPLACE_CHAR = "?"
22+
ENCMAP = []
23+
for i in range(8):
24+
ENCMAP.append({k: v[i] for k, v in SEQUENCES.items()})
2525

2626

27-
class DNAError(ValueError):
28-
pass
29-
30-
31-
class DNADecodeError(DNAError):
32-
pass
33-
34-
35-
def dna_encode(n):
36-
def encode(text, errors="strict"):
37-
r = ""
38-
for c in text:
39-
bs = "{:0>8}".format(bin(ord(c))[2:])
40-
for i in range(0, 8, 2):
41-
r += ENCMAP[bs[i:i+2]][n-1]
42-
return r, len(text)
43-
return encode
44-
45-
46-
def dna_decode(n):
47-
def decode(text, errors="strict"):
48-
r = ""
49-
text = text.upper()
50-
for i in range(0, len(text), 4):
51-
bs = ""
52-
for j, c in enumerate(text[i:i+4]):
53-
try:
54-
bs += DECMAP[n-1][c]
55-
except KeyError:
56-
if errors == "strict":
57-
raise DNADecodeError("'dna' codec can't decode "
58-
"character '{}' in position {}"
59-
.format(c, i + j))
60-
elif errors == "replace":
61-
bs += 2 * REPLACE_CHAR
62-
elif errors == "ignore":
63-
continue
64-
else:
65-
raise ValueError("Unsupported error handling {}"
66-
.format(errors))
67-
try:
68-
r += chr(int(bs, 2))
69-
except ValueError:
70-
if len(bs) > 0:
71-
r += "[" + bs + "]"
72-
return r, len(text)
73-
return decode
74-
75-
76-
add("dna", dna_encode, dna_decode, r"dna[-_]?([1-8])$")
27+
add_map("dna", ENCMAP, binary=True, pattern=r"dna[-_]?([1-8])$")

codext/stegano/leetspeak.py

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,10 @@
77
- decodes file content to str (read)
88
- encodes file content from str to bytes (write)
99
"""
10-
try: # Python 2
11-
from string import maketrans
12-
except ImportError: # Python 3
13-
maketrans = str.maketrans
14-
1510
from ..__common__ import *
1611

1712

18-
alph = "abeiostABEIOSTZ", "483105748310572"
19-
to_leet = maketrans(*alph)
20-
from_leet = maketrans(*alph[::-1])
21-
22-
23-
def leet_encode(text, errors="strict"):
24-
r = text.translate(to_leet)
25-
return r, len(r)
26-
27-
28-
def leet_decode(text, errors="strict"):
29-
r = text.translate(from_leet)
30-
return r, len(r)
13+
ENCMAP = {k: v for k, v in zip("abeiostABEIOSTZ", "483105748310572")}
3114

3215

33-
add("leet", leet_encode, leet_decode, r"(?:leet|1337|leetspeak)$")
16+
add_map("leet", ENCMAP, pattern=r"(?:leet|1337|leetspeak)$", no_error=True)

0 commit comments

Comments
 (0)