Skip to content

Commit eb0b6d7

Browse files
committed
Refined codec: vigenere (2)
1 parent 9b8d574 commit eb0b6d7

File tree

3 files changed

+72
-31
lines changed

3 files changed

+72
-31
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ This category also contains `ascii85`, `adobe`, `[x]btoa`, `zeromq` with the `ba
282282

283283
- [X] `affine`: aka Affine Cipher
284284
- [X] `atbash`: aka Atbash Cipher
285+
- [X] `autoclave`: aka Autoclave/Autokey Cipher (variant of Vigenere Cipher)
285286
- [X] `bacon`: aka Baconian Cipher
286287
- [X] `barbie-N`: aka Barbie Typewriter (*N* belongs to [1, 4])
287288
- [X] `beaufort`: aka Beaufort Cipher (variant of Vigenere Cipher)

docs/pages/enc/crypto.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,23 @@ It implements the monoalphabetic substitution cipher used for the Hebrew alphabe
7171

7272
-----
7373

74+
### Autoclave/Autokey Cipher
75+
76+
This is a variant of the [Vigenere Cipher](#vigenere-cipher) using a key stream generated from the primer key and the message appended.
77+
78+
**Codec** | **Conversions** | **Aliases** | **Comment**
79+
:---: | :---: | --- | ---
80+
`autoclave` | text <-> Autoclave ciphertext | `autoclave-cipher`, `autokey` |
81+
82+
```python
83+
>>> codext.encode("This is a test !", "autoclave-test")
84+
'Mlal bz i lmkt !'
85+
>>> codext.decode("Mlal bz i lmkt !", "autokey_cipher-test")
86+
'This is a test !'
87+
```
88+
89+
-----
90+
7491
### Baconian Cipher
7592

7693
It support only letters.

src/codext/crypto/vigenere.py

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,54 +11,77 @@
1111

1212
from ..__common__ import *
1313

14-
__examples__ = {
15-
'enc(beaufort)': None,
16-
'enc(beaufort-lemon)': {'ATTACKATDAWN': 'LLTOLBETLNPR'},
17-
'enc(beaufort-key)': {'hello': 'danzq'},
18-
'enc(beaufort_key)': {'Hello World': 'Danzq Cwnnh'},
19-
'enc(trithemius-cipher)': {'this is a test': "tikv mx g ambd"},
20-
'enc(trithemius)': {'HELLO': "HFNOS", '12345!@#$': "12345!@#$"},
21-
'enc(vigenere)': None,
22-
'enc(vigenere-lemon)': {'ATTACKATDAWN': 'LXFOPVEFRNHR'},
23-
'enc(vigenere-key)': {'hello': 'rijvs'},
24-
'enc(vigenère_key)': {'Hello World': 'Rijvs Uyvjn'},
25-
'enc-dec(beaufort-secret)': ['hello world', 'ATTACK AT DAWN', 'Test 1234!'],
26-
'enc-dec(trithemius)': ["Hello, World!", "@random"],
27-
'enc-dec(vigenere-secret)': ['hello world', 'ATTACK AT DAWN', 'Test 1234!'],
14+
__examples1__ = {
15+
'enc(autoclave)': None,
16+
'enc(autokey-queenly)': {'ATTACKATDAWN': 'QNXEPVYTWTWP'},
17+
'enc-dec(autoclave-key)': ['hello world', 'ATTACK AT DAWN', 'Test 1234!', 'Mixed Case 123'],
2818
}
29-
__guess__ = ["beaufort-key", "beaufort-secret", "beaufort-password", "trithemius",
30-
"vigenere-key", "vigenere-secret", "vigenere-password"]
19+
__examples2__ = {
20+
'enc(beaufort)': None,
21+
'enc(beaufort-lemon)': {'ATTACKATDAWN': 'LLTOLBETLNPR'},
22+
'enc(beaufort-key)': {'hello': 'danzq'},
23+
'enc(beaufort_key)': {'Hello World': 'Danzq Cwnnh'},
24+
'enc-dec(beaufort-secret)': ['hello world', 'ATTACK AT DAWN', 'Test 1234!'],
25+
}
26+
__examples3__ = {
27+
'enc(trithemius-cipher)': {'this is a test': "tikv mx g ambd"},
28+
'enc(trithemius)': {'HELLO': "HFNOS", '12345!@#$': "12345!@#$"},
29+
'enc-dec(trithemius)': ["Hello, World!", "@random"],
30+
}
31+
__examples4__ = {
32+
'enc(vigenere)': None,
33+
'enc(vigenere-lemon)': {'ATTACKATDAWN': 'LXFOPVEFRNHR'},
34+
'enc(vigenere-key)': {'hello': 'rijvs'},
35+
'enc(vigenère_key)': {'Hello World': 'Rijvs Uyvjn'},
36+
'enc-dec(vigenere-secret)': ['hello world', 'ATTACK AT DAWN', 'Test 1234!'],
37+
}
38+
__guess1__ = ["autoclave-key", "autoclave-password", "autoclave-secret"]
39+
__guess2__ = ["beaufort-key", "beaufort-password", "beaufort-secret"]
40+
__guess3__ = ["trithemius"]
41+
__guess4__ = ["vigenere-key", "vigenere-password", "vigenere-secret"]
42+
43+
44+
bchar = lambda c, k, i, d=False: (LC if (b := c in LC) else UC)[(ord(k[i % len(k)]) - ord('a') - \
45+
(ord(c) - ord("Aa"[b]))) % 26]
46+
vchar = lambda c, k, i, d=False: (LC if (b := c in LC) else UC)[(ord(c) - ord("Aa"[b]) + \
47+
[1, -1][d] * (ord(k[i % len(k)]) - ord('a'))) % 26]
3148

3249

33-
def __make(enc, cfunc):
34-
def code(decode=False):
50+
def __make(enc, char_func, key_stream=False):
51+
def _code(decode=False):
3552
def _wrapper(key):
3653
def _subwrapper(text, errors="strict"):
37-
k = key.lower()
38-
if not k or not k.isalpha():
54+
if not (k := key.lower()) or not k.isalpha():
3955
raise LookupError(f"Bad parameter for encoding '{enc}': key must be a non-empty alphabetic string")
56+
if key_stream and not decode:
57+
k += "".join(c.lower() for c in ensure_str(text) if c in LC or c in UC)
4058
result, i = [], 0
59+
if key_stream and decode:
60+
k = list(k)
4161
for c in ensure_str(text):
4262
if c in LC or c in UC:
43-
result.append(cfunc(c, k, i, decode))
63+
result.append(dc := char_func(c, k, i, decode))
64+
if key_stream and decode:
65+
k.append(dc.lower())
4466
i += 1
4567
else:
4668
result.append(c)
47-
r = "".join(result)
48-
return r, len(r)
69+
return (r := "".join(result)), len(r)
4970
return _subwrapper
5071
return _wrapper
51-
return code(), code(True)
72+
return _code(), _code(True)
5273

5374

54-
bchar = lambda c, k, i, d=False: (LC if (b := c in LC) else UC)[(ord(k[i % len(k)]) - ord('a') - \
55-
(ord(c) - ord("Aa"[b]))) % 26]
56-
add("beaufort", *__make("beaufort", bchar), r"beaufort(?:[-_]cipher)?(?:[-_]([a-zA-Z]+))?$", penalty=.1)
75+
add("autoclave", *__make("autoclave", vchar, True), r"auto(?:clave|key)(?:[-_]cipher)?(?:[-_]([a-zA-Z]+))?$",
76+
examples=__examples1__, guess=__guess1__, penalty=.1)
77+
78+
add("beaufort", *__make("beaufort", bchar), r"beaufort(?:[-_]cipher)?(?:[-_]([a-zA-Z]+))?$",
79+
examples=__examples2__, guess=__guess2__, penalty=.1)
5780

58-
vchar = lambda c, k, i, d=False: (LC if (b := c in LC) else UC)[(ord(c) - ord("Aa"[b]) + \
59-
[1, -1][d] * (ord(k[i % len(k)]) - ord('a'))) % 26]
6081
enc, dec = __make("trithemius", vchar)
61-
add("trithemius", enc(k := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), dec(k), r"trithemius(?:[-_]cipher)?$", penalty=.1)
82+
add("trithemius", enc(k := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), dec(k), r"trithemius(?:[-_]cipher)?$",
83+
examples=__examples3__, guess=__guess3__, penalty=.1)
6284

63-
add("vigenere", *__make("vigenere", vchar), r"vigen[eè]re(?:[-_]cipher)?(?:[-_]([a-zA-Z]+))?$", penalty=.1)
85+
add("vigenere", *__make("vigenere", vchar), r"vigen[eè]re(?:[-_]cipher)?(?:[-_]([a-zA-Z]+))?$",
86+
examples=__examples4__, guess=__guess4__, penalty=.1)
6487

0 commit comments

Comments
 (0)