Extended Straddling Checkerboard: Difference between revisions
Content added Content deleted
(Changed task description (as discussed in Talk Page) and amended the Wren entry accordingly.) |
|||
Line 280: | Line 280: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
See the discussion for the different checkerboard table handling. |
|||
<syntaxhighlight lang="python">""" rosettacode.org/wiki/Extended_Straddling_Checkerboard """ |
<syntaxhighlight lang="python">""" rosettacode.org/wiki/Extended_Straddling_Checkerboard """ |
||
Line 294: | Line 295: | ||
'SUPP': 'π', |
'SUPP': 'π', |
||
} |
} |
||
# reversed WDICT for reverse lookup on decode |
|||
SDICT = {v: k for (k, v) in WDICT.items()} |
|||
# CT37w at https://www.ciphermachinesandcryptology.com/en/table.htm |
|||
# web site CT37w, but '/' (FIG) char is 98 not 99 to help differentiate from code for 9 of '999' |
|||
CT37w = [['', 'A', 'E', 'I', 'N', 'O', 'T', 'κ', '', '', '',], |
CT37w = [['', 'A', 'E', 'I', 'N', 'O', 'T', 'κ', '', '', '',], |
||
['7', 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M',], |
['7', 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M',], |
||
['8', 'P', 'Q', 'R', 'S', 'U', 'V', 'W', 'X', 'Y', 'Z',], |
['8', 'P', 'Q', 'R', 'S', 'U', 'V', 'W', 'X', 'Y', 'Z',], |
||
['9', ' ', '.', 'α', 'ρ', 'μ', 'ν', 'γ', 'σ', ' |
['9', ' ', '.', 'α', 'ρ', 'μ', 'ν', 'γ', 'σ', 'π', '/'],] |
||
# Modified CT37w: web site CT37w, but exchange '/' (FIG) char and 'π' |
|||
# to help differentiate the '999' encoding for a '9' from a terminator code |
|||
CT37w_mod = [['', 'A', 'E', 'I', 'N', 'O', 'T', 'κ', '', '', '',], |
|||
['7', 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M',], |
|||
['8', 'P', 'Q', 'R', 'S', 'U', 'V', 'W', 'X', 'Y', 'Z',], |
|||
['9', ' ', '.', 'α', 'ρ', 'μ', 'ν', 'γ', 'σ', '/', 'π',],] |
|||
def xcb_encode(message, |
def xcb_encode(message, table=CT37w, code='κ', wdict=WDICT): |
||
""" |
""" |
||
Encode with extended straddling checkerboard. Default checkerboard is |
Encode with extended straddling checkerboard. Default checkerboard is |
||
Line 313: | Line 322: | ||
numericmode, codemode = False, False |
numericmode, codemode = False, False |
||
codemodecount = 0 |
codemodecount = 0 |
||
if table[-1][-1] == '/': |
|||
nchangemode = '99' |
|||
digit_repeats = 3 |
|||
else: |
|||
nchangemode = '98' |
|||
digit_repeats = 2 |
|||
# replace terms found in dictionary with a single char symbol that is in the table |
# replace terms found in dictionary with a single char symbol that is in the table |
||
s = reduce(lambda x, p: x.replace( |
s = reduce(lambda x, p: x.replace( |
||
p[0], p[1]), wdict.items(), message.upper()) |
p[0], p[1]), wdict.items(), message.upper()) |
||
for c in s: |
for c in s: |
||
if c.isnumeric(): |
if c.isnumeric(): |
||
if codemode: # codemode symbols are preceded by the CODE digit '6' then as-is |
if codemode: # codemode symbols are preceded by the CODE digit '6' then as-is |
||
encoded.append(c) |
encoded.append(c) |
||
codemodecount += 1 |
codemodecount += 1 |
||
Line 324: | Line 340: | ||
codemode = False |
codemode = False |
||
else: |
else: |
||
if not numericmode: |
if not numericmode: |
||
numericmode = True |
numericmode = True |
||
encoded.append(nchangemode) # FIG |
encoded.append(nchangemode) # FIG |
||
encoded.append(c* |
encoded.append(c*digit_repeats) |
||
else: |
else: |
||
codemode = False |
codemode = False |
||
if numericmode: |
if numericmode: |
||
# end numericmode with the FIG numeric code for '/' (98) |
|||
encoded.append(nchangemode) |
|||
numericmode = False |
numericmode = False |
||
Line 350: | Line 367: | ||
def xcb_decode(s, |
def xcb_decode(s, table=CT37w, code='κ', sdict=SDICT): |
||
""" Decode extended straddling checkerboard """ |
""" Decode extended straddling checkerboard """ |
||
⚫ | |||
prefixes = sorted([row[0] for row in table], reverse=True) |
prefixes = sorted([row[0] for row in table], reverse=True) |
||
pos = 0 |
pos, numericmode, codemode = 0, False, False |
||
⚫ | |||
codemode = False |
|||
decoded = [] |
decoded = [] |
||
if table[-1][-1] == '/': |
|||
nchangemode = '99' |
|||
digit_repeats = 3 |
|||
else: |
|||
nchangemode = '98' |
|||
digit_repeats = 2 |
|||
⚫ | |||
while pos < len(s): |
while pos < len(s): |
||
if numericmode: |
if numericmode: |
||
if s[pos:pos+ |
if s[pos:pos+digit_repeats] in numbers: |
||
decoded.append(numbers[s[pos:pos+ |
decoded.append(numbers[s[pos:pos+digit_repeats]]) |
||
pos += |
pos += digit_repeats - 1 |
||
elif s[pos:pos+2] == nchangemode: |
elif s[pos:pos+2] == nchangemode: |
||
numericmode = False |
numericmode = False |
||
pos += 1 |
pos += 1 |
||
elif decoded[-1] == '9': # error, so backtrack if last was 9 |
|||
decoded.pop() |
|||
⚫ | |||
pos -= digit_repeats - 1 |
|||
elif codemode: |
elif codemode: |
||
Line 377: | Line 402: | ||
numericmode = not numericmode |
numericmode = not numericmode |
||
pos += 1 |
pos += 1 |
||
else: |
else: |
||
for p in prefixes: |
for p in prefixes: |
||
Line 386: | Line 412: | ||
if c == code: |
if c == code: |
||
codemode = True |
codemode = True |
||
pos += n |
pos += n |
||
break |
break |
||
Line 400: | Line 427: | ||
print('Encoded: ', xcb_encode(MESSAGE)) |
print('Encoded: ', xcb_encode(MESSAGE)) |
||
print('Decoded: ', xcb_decode(xcb_encode(MESSAGE))) |
print('Decoded: ', xcb_decode(xcb_encode(MESSAGE))) |
||
print('Encoded: ', xcb_encode(MESSAGE, CT37w_mod)) |
|||
print('Decoded: ', xcb_decode(xcb_encode(MESSAGE, CT37w_mod), CT37w_mod)) |
|||
</syntaxhighlight>{{out}} |
</syntaxhighlight>{{out}} |
||
<pre> |
<pre> |
||
Admin ACK your MSG. CODE291 SEND further 2000 SUPP to HQ by 1 March |
Admin ACK your MSG. CODE291 SEND further 2000 SUPP to HQ by 1 March |
||
Encoded: 072792390929088484829094919062919097907384825751829099222000000000999098905490758190708890991119990790827175 |
|||
Encoded: 072792390929088484829094919062919097907384825751829098222000000000989099905490758190708890981119890790827175 |
|||
Decoded: ADMIN ACK YOUR MSG. CODE291 SEND FURTHER 2000 SUPP TO HQ BY 1 MARCH |
|||
Encoded: 0727923909290884848290949190629190979073848257518290982200000098909990549075819070889098119890790827175 |
|||
Decoded: ADMIN ACK YOUR MSG. CODE291 SEND FURTHER 2000 SUPP TO HQ BY 1 MARCH |
Decoded: ADMIN ACK YOUR MSG. CODE291 SEND FURTHER 2000 SUPP TO HQ BY 1 MARCH |
||
</pre> |
</pre> |