|
|
|
@ -7,6 +7,7 @@ TEXTLINE_OFFSET = -1
|
|
|
|
|
DEFAULT_PAD_WIDTH = 72
|
|
|
|
|
CIPHER_FLOOR = 1
|
|
|
|
|
CIPHER_CEIL = 25
|
|
|
|
|
NULLCHAR = '.'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def encode(msg, pad):
|
|
|
|
@ -52,7 +53,7 @@ def _as_line_chunks(chars, width=DEFAULT_PAD_WIDTH):
|
|
|
|
|
yield ''.join(chunk)
|
|
|
|
|
chunk = []
|
|
|
|
|
if len(chunk) < width:
|
|
|
|
|
chunk += (['.'] * (width - len(chunk)))
|
|
|
|
|
chunk += ([NULLCHAR] * (width - len(chunk)))
|
|
|
|
|
yield ''.join(chunk)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -66,24 +67,38 @@ def _padfill(text, padlines):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _cipherfill(padfilled_lines):
|
|
|
|
|
padline = textline = None
|
|
|
|
|
for i, line in enumerate(padfilled_lines):
|
|
|
|
|
if _is_padline(i):
|
|
|
|
|
padline = line
|
|
|
|
|
elif _is_textline(i):
|
|
|
|
|
textline = line
|
|
|
|
|
else:
|
|
|
|
|
cipherline = \
|
|
|
|
|
_get_cipherline_from_padline_and_textline(padline, textline)
|
|
|
|
|
padfilled_lines[i] = cipherline
|
|
|
|
|
|
|
|
|
|
return padfilled_lines
|
|
|
|
|
lineno = i + 1
|
|
|
|
|
if _is_cipherline(lineno):
|
|
|
|
|
padline = padfilled_lines[i - abs(PADLINE_OFFSET)]
|
|
|
|
|
textline = padfilled_lines[i - abs(TEXTLINE_OFFSET)]
|
|
|
|
|
yield padline
|
|
|
|
|
yield textline
|
|
|
|
|
yield _cipherline_from_padline_and_textline(padline, textline)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _get_cipherline_from_padline_and_textline(padline, textline):
|
|
|
|
|
def _cipherline_from_padline_and_textline(padline, textline):
|
|
|
|
|
ret = []
|
|
|
|
|
for padchar, textchar in izip(padline, textline):
|
|
|
|
|
idx = (_AS_NUMS[padchar] + _AS_NUMS[textchar]) % CIPHER_CEIL
|
|
|
|
|
if textchar == NULLCHAR:
|
|
|
|
|
ret.append(NULLCHAR)
|
|
|
|
|
continue
|
|
|
|
|
charnum = _AS_NUMS[padchar] + _AS_NUMS[textchar]
|
|
|
|
|
idx = charnum if charnum <= CIPHER_CEIL else charnum % CIPHER_CEIL
|
|
|
|
|
ret.append(_AS_ALPHA[idx])
|
|
|
|
|
return ''.join(ret)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _textline_from_cipherline_and_padline(cipherline, padline):
|
|
|
|
|
ret = []
|
|
|
|
|
for ciphercar, padchar in izip(cipherline, padline):
|
|
|
|
|
if ciphercar == NULLCHAR:
|
|
|
|
|
ret.append(NULLCHAR)
|
|
|
|
|
continue
|
|
|
|
|
charnum = _AS_NUMS[ciphercar] - _AS_NUMS[padchar]
|
|
|
|
|
idx = charnum if charnum <= CIPHER_CEIL else charnum % CIPHER_CEIL
|
|
|
|
|
if idx < 0:
|
|
|
|
|
idx = CIPHER_CEIL + idx
|
|
|
|
|
ret.append(_AS_ALPHA[idx])
|
|
|
|
|
return ''.join(ret)
|
|
|
|
|
|
|
|
|
|