Extended Straddling Checkerboard: Difference between revisions

m
(Changed task description (as discussed in Talk Page) and amended the Wren entry accordingly.)
Line 280:
 
=={{header|Python}}==
See the discussion for the different checkerboard table handling.
<syntaxhighlight lang="python">""" rosettacode.org/wiki/Extended_Straddling_Checkerboard """
 
Line 294 ⟶ 295:
'SUPP': 'π',
}
SDICT = {v: k for (k, v) in WDICT.items()} # 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', 'κ', '', '', '',],
['7', 'B', 'C', 'D', 'F', 'G', 'H', 'J', 'K', 'L', 'M',],
['8', 'P', 'Q', 'R', 'S', 'U', 'V', 'W', 'X', 'Y', 'Z',],
['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, nchangemodetable='98'CT37w, code='κ', table=CT37w, wdict=WDICT):
"""
Encode with extended straddling checkerboard. Default checkerboard is
Line 313 ⟶ 322:
numericmode, codemode = False, False
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
s = reduce(lambda x, p: x.replace(
p[0], p[1]), wdict.items(), message.upper())
for c in s:
if c.isnumeric():
if codemode: # codemode symbols are preceded by the CODE digit '6' then as-is
encoded.append(c)
codemodecount += 1
Line 324 ⟶ 340:
codemode = False
 
else: # numeric numbers are triplicate encoded so '3' -> '333'
if not numericmode:
numericmode = True
encoded.append(nchangemode) # FIG
 
encoded.append(c*3digit_repeats)
 
else:
codemode = False
if numericmode:
encoded.append(nchangemode) # end numericmode with the FIG numeric code for '/' (98)
encoded.append(nchangemode)
numericmode = False
 
Line 350 ⟶ 367:
 
 
def xcb_decode(s, nchangemodetable='98'CT37w, code='κ', table=CT37w, sdict=SDICT):
""" Decode extended straddling checkerboard """
numbers = {c*3: c for c in list('0123456789')}
prefixes = sorted([row[0] for row in table], reverse=True)
pos, numericmode, codemode = 0, False, False
numericmode = False
codemode = False
decoded = []
if table[-1][-1] == '/':
nchangemode = '99'
digit_repeats = 3
else:
nchangemode = '98'
digit_repeats = 2
numbers = {c*3digit_repeats: c for c in list('0123456789')}
while pos < len(s):
if numericmode:
if s[pos:pos+3digit_repeats] in numbers:
decoded.append(numbers[s[pos:pos+3digit_repeats]])
pos += 2digit_repeats - 1
elif s[pos:pos+2] == nchangemode:
numericmode = False
pos += 1
elif decoded[-1] == '9': # error, so backtrack if last was 9
decoded.pop()
numericmode = False
pos -= digit_repeats - 1
 
elif codemode:
Line 377 ⟶ 402:
numericmode = not numericmode
pos += 1
 
else:
for p in prefixes:
Line 386 ⟶ 412:
if c == code:
codemode = True
 
pos += n
break
Line 400 ⟶ 427:
print('Encoded: ', 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}}
<pre>
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
</pre>
4,108

edits