|
| 1 | +# -*- coding: UTF-8 -*- |
| 2 | +"""Vernam Cipher Codec - vernam content encoding. |
| 3 | +
|
| 4 | +The Vernam cipher, patented by Gilbert Vernam in 1919, XORs each character of the text with the corresponding character |
| 5 | + of a repeated key ; with a random key as long as the text, used only once, it becomes the one-time pad. As XOR is its |
| 6 | + own inverse, decoding is the same as encoding. |
| 7 | +
|
| 8 | +This codec: |
| 9 | +- en/decodes strings from str to str |
| 10 | +- en/decodes strings from bytes to bytes |
| 11 | +- decodes file content to str (read) |
| 12 | +- encodes file content from str to bytes (write) |
| 13 | +
|
| 14 | +Reference: https://en.wikipedia.org/wiki/Gilbert_Vernam |
| 15 | +""" |
| 16 | +from ..__common__ import * |
| 17 | + |
| 18 | + |
| 19 | +__examples__ = { |
| 20 | + 'enc(vernam|vernam-cipher)': None, |
| 21 | + 'enc(vernam-key)': {'this is a test': "\x1f\r\x10\x18E\x10\x18E\x18K\x11\x1c\x18\x11"}, |
| 22 | + 'enc(vernam_cipher-Key)': {'this is a test': "?\r\x108E\x108E\x18k\x11\x1c8\x11"}, |
| 23 | + 'dec(vernam-key)': {"\x1f\r\x10\x18E\x10\x18E\x18K\x11\x1c\x18\x11": 'this is a test'}, |
| 24 | + 'enc-dec(vernam-secret|vernam-a b!)': ["", "this is a test", "@random{256}", "Caf\xe9 €"], |
| 25 | +} |
| 26 | +__guess__ = ["vernam-key", "vernam-password", "vernam-secret"] |
| 27 | + |
| 28 | + |
| 29 | +def vernam(key=None): |
| 30 | + def code(text, errors="strict"): |
| 31 | + if not key: |
| 32 | + raise LookupError("Bad parameter for encoding 'vernam': key must be a non-empty string") |
| 33 | + r = "".join(chr(ord(c) ^ ord(key[i % len(key)])) for i, c in enumerate(ensure_str(text))) |
| 34 | + return r, len(r) |
| 35 | + return code |
| 36 | + |
| 37 | + |
| 38 | +add("vernam", vernam, vernam, r"^vernam(?:[-_]cipher)?(?:[-_](.+))?$", examples=__examples__, guess=__guess__, |
| 39 | + transitive=True, penalty=.1) |
0 commit comments