Skip to content

Commit f006851

Browse files
committed
Added new codec: bacon
1 parent c37f822 commit f006851

3 files changed

Lines changed: 34 additions & 131 deletions

File tree

codext/crypto/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# -*- coding: UTF-8 -*-
2+
from .bacon import *
23
from .barbie import *
34
from .rotn import *
45
from .xor_byte import *

codext/crypto/bacon.py

Lines changed: 5 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -13,137 +13,11 @@
1313

1414

1515
ENCMAP = {
16-
'A': "aaaaa",
16+
'A': "aaaaa", 'B': "aaaab", 'C': "aaaba", 'D': "aaabb", 'E': "aabaa", 'F': "aabab", 'G': "aabba", 'H': "aabbb",
17+
'I': "abaaa", 'J': "abaaa", 'K': "abaab", 'L': "ababa", 'M': "ababb", 'N': "abbaa", 'O': "abbab", 'P': "abbba",
18+
'Q': "abbbb", 'R': "baaaa", 'S': "baaab", 'T': "baaba", 'U': "baabb", 'V': "baabb", 'W': "babaa", 'X': "babab",
19+
'Y': "babba", 'Z': "babbb", ' ': "",
1720
}
18-
REPLACE_CHAR = "?"
19-
20-
#FIXME
21-
"""
22-
VERSION 1
23-
24-
Letter Code Binary
25-
A aaaaa 00000
26-
B aaaab 00001
27-
C aaaba 00010
28-
D aaabb 00011
29-
E aabaa 00100
30-
F aabab 00101
31-
G aabba 00110
32-
H aabbb 00111
33-
I, J abaaa 01000
34-
K abaab 01001
35-
L ababa 01010
36-
M ababb 01011
37-
38-
Letter Code Binary
39-
N abbaa 01100
40-
O abbab 01101
41-
P abbba 01110
42-
Q abbbb 01111
43-
R baaaa 10000
44-
S baaab 10001
45-
T baaba 10010
46-
U, V baabb 10011
47-
W babaa 10100
48-
X babab 10101
49-
Y babba 10110
50-
Z babbb 10111
51-
52-
Letter Code Binary
53-
A aaaaa 00000
54-
B aaaab 00001
55-
C aaaba 00010
56-
D aaabb 00011
57-
E aabaa 00100
58-
F aabab 00101
59-
G aabba 00110
60-
H aabbb 00111
61-
I abaaa 01000
62-
J abaab 01001
63-
K ababa 01010
64-
L ababb 01011
65-
M abbaa 01100
66-
67-
VERSION 2
68-
69-
Letter Code Binary
70-
N abbab 01101
71-
O abbba 01110
72-
P abbbb 01111
73-
Q baaaa 10000
74-
R baaab 10001
75-
S baaba 10010
76-
T baabb 10011
77-
U babaa 10100
78-
V babab 10101
79-
W babba 10110
80-
X babbb 10111
81-
Y bbaaa 11000
82-
Z bbaab 11001
83-
"""
84-
85-
class BaconError(ValueError):
86-
pass
87-
88-
89-
class BaconDecodeError(BaconError):
90-
pass
91-
92-
93-
class BaconEncodeError(BaconError):
94-
pass
95-
96-
97-
def bacon_encode(code):
98-
def encode(text, errors="strict"):
99-
std0, stdn = [c for c in STD[0]], [c for c in STD[code]]
100-
spec0, specn = SPEC[0].split(), SPEC[code].split()
101-
mapping = {d: e for d, e in zip(std0 + spec0, stdn + specn)}
102-
r = ""
103-
for i, c in enumerate(ensure_str(text)):
104-
try:
105-
r += mapping[c]
106-
except KeyError:
107-
if errors == "strict":
108-
raise BaconEncodeError("'bacon' codec can't encode"
109-
" character '{}' in position {}"
110-
.format(c, i))
111-
elif errors == "replace":
112-
r += REPLACE_CHAR
113-
elif errors == "ignore":
114-
continue
115-
else:
116-
raise ValueError("Unsupported error handling {}"
117-
.format(errors))
118-
return r, len(text)
119-
return encode
120-
121-
122-
def bacon_decode(code):
123-
def decode(text, errors="strict"):
124-
std0, stdn = [c for c in STD[0]], [c for c in STD[code]]
125-
spec0, specn = SPEC[0].split(), SPEC[code].split()
126-
mapping = {e: d for d, e in zip(std0 + spec0, stdn + specn)}
127-
r = ""
128-
for i, c in enumerate(ensure_str(text)):
129-
try:
130-
r += mapping[c]
131-
except KeyError:
132-
if errors == "strict":
133-
raise BaconDecodeError("'bacon' codec can't decode"
134-
" character '{}' in position {}"
135-
.format(c, i))
136-
elif errors == "replace":
137-
r += REPLACE_CHAR
138-
elif errors == "ignore":
139-
continue
140-
else:
141-
raise ValueError("Unsupported error handling {}"
142-
.format(errors))
143-
return r, len(text)
144-
return decode
14521

14622

147-
# note: the integer behind "bacon" is captured for sending to the
148-
# parametrizable encode and decode functions "bacon_**code"
149-
add("bacon", bacon_encode, bacon_decode, r"bacon(?:onian[-_]cipher)$")
23+
add_map("bacon", ENCMAP, sep=" ", ignore_case=True, pattern=r"bacon(?:(?:ian)?[-_]cipher)?([\-_].{2})?$")

tests/test_bacon.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python
2+
# -*- coding: UTF-8 -*-
3+
"""Bacon codec tests.
4+
5+
"""
6+
from unittest import TestCase
7+
8+
from codext.__common__ import *
9+
10+
11+
class TestCodecBaconianCipher(TestCase):
12+
def test_codec_bacon(self):
13+
STR = "this is a test"
14+
BCN1 = "baaba aabbb abaaa baaab abaaa baaab aaaaa baaba aabaa baaab baaba"
15+
BCN2 = "10010 00111 01000 10001 01000 10001 00000 10010 00100 10001 10010"
16+
self.assertEqual(codecs.encode(b(STR), "bacon"), b(BCN1))
17+
self.assertEqual(codecs.encode(b(STR), "bacon-ab"), b(BCN1))
18+
self.assertEqual(codecs.encode(b(STR), "bacon-AB"), b(BCN1.upper()))
19+
self.assertEqual(codecs.encode(b(STR), "bacon-01"), b(BCN2))
20+
self.assertRaises(ValueError, codecs.encode, "\r", "bacon")
21+
self.assertRaises(ValueError, codecs.decode, "\r", "bacon-AB")
22+
self.assertRaises(ValueError, codecs.decode, BCN1, "bacon-01")
23+
self.assertEqual(codecs.decode(b(BCN2), "bacon-01"), b(STR.upper()))
24+
self.assertIsNotNone(codecs.encode("test\r", "bacon_cipher", "replace"))
25+
self.assertIsNotNone(codecs.decode("test\r", "baconian-cipher", "replace"))
26+
self.assertIsNotNone(codecs.encode("test\r", "bacon_cipher", "ignore"))
27+
self.assertIsNotNone(codecs.decode("test\r", "baconian-cipher", "ignore"))
28+
self.assertRaises(ValueError, codecs.encode, "\r", "baconian-cipher", "BAD")

0 commit comments

Comments
 (0)