|
| 1 | +# -*- coding: UTF-8 -*- |
| 2 | +"""Rail Fence Cipher Codec - rail fence encoding. |
| 3 | +
|
| 4 | +This codec: |
| 5 | +- en/decodes strings from str to str |
| 6 | +- en/decodes strings from bytes to bytes |
| 7 | +- decodes file content to str (read) |
| 8 | +- encodes file content from str to bytes (write) |
| 9 | +""" |
| 10 | + |
| 11 | + |
| 12 | + |
| 13 | +from ..__common__ import * |
| 14 | + |
| 15 | + |
| 16 | +__examples__ = { |
| 17 | + 'enc(rail-5-3|rail_5_3)': {'this is a test' : 'it sss etiath '}, |
| 18 | + 'enc(rail-5-3-up|rail_5_3-up)' :{'this is a test': 'h tiats e ssit'}, |
| 19 | + 'dec(rail-7-4|rail_7_4)': {'a stiet shsti': 'this is a test'} |
| 20 | +} |
| 21 | + |
| 22 | + |
| 23 | + |
| 24 | +def __buildf(text, rails, offset = 0, up = 0) : |
| 25 | + l, rail = len(text), offset |
| 26 | + if up != '' : |
| 27 | + dr = -1 |
| 28 | + rail = rails - offset - 1 |
| 29 | + else : |
| 30 | + dr = 1 |
| 31 | + |
| 32 | + f = [["#"] * l for i in range(rails)] |
| 33 | + |
| 34 | + for x in range(l) : |
| 35 | + f[rail][x] = text[x] |
| 36 | + if rail >= rails - 1: |
| 37 | + dr = -1 |
| 38 | + elif rail <= 0: |
| 39 | + dr = 1 |
| 40 | + rail += dr |
| 41 | + return f |
| 42 | + |
| 43 | +def railfence_encode(rails = 3, offset = 0, up = 0) : |
| 44 | + def encode(text, errors="strict") : |
| 45 | + c,l = '', len(text) |
| 46 | + f = __buildf(text, rails, offset, up) |
| 47 | + for r in range(rails) : |
| 48 | + for x in range(l) : |
| 49 | + if f[r][x] != '#' : |
| 50 | + c += f[r][x] |
| 51 | + return c, l |
| 52 | + return encode |
| 53 | + |
| 54 | +def railfence_decode(rails = 3, offset = 0, up = 0) : |
| 55 | + def decode(text, errors = 'strict') : |
| 56 | + f = __buildf("x" * len(text), rails, offset, up) |
| 57 | + plain, i = '', 0 |
| 58 | + ra, l = range(rails), range(len(text)) |
| 59 | + |
| 60 | + #Put the characters in the right place |
| 61 | + for r in ra: |
| 62 | + for x in l : |
| 63 | + if f[r][x] == "x" : |
| 64 | + f[r][x] = text[i] |
| 65 | + i += 1 |
| 66 | + #Read the characters in the right order |
| 67 | + for x in l : |
| 68 | + for r in ra: |
| 69 | + if f[r][x] != '#' : |
| 70 | + plain += f[r][x] |
| 71 | + |
| 72 | + return plain, len(plain) |
| 73 | + |
| 74 | + return decode |
| 75 | + |
| 76 | +add("rail", railfence_encode, railfence_decode, r"rail[-_](\d+)[-_](\d+)[-_]?(up)?$") |
0 commit comments