words = ['HETEAMT','TOWIMO','NNSEJN','DTOSEB','RERRHO','OISSMI','URNORI','SHIROR']
ctext = ''.join(words)
l = len(ctext)
print('\ntotal chars', l)
key = '7456321'
n = len(key)
print('\nkey length', n)
# here we do exactly the same as what you did to encode, except we just
# count the letters. so chars[x] is the number of characters in column x,
# which starts at 0 and is added 1 or 2 on each line.
chars = [0] * n
remaining = l
ichar = 0
chunk = 0
while remaining > 0:
k = min(chunk+1, remaining)
chars[ichar] += k
remaining -= k
ichar = (ichar + 1) % n # this indexes the columns 0..n-1,0..n-1,...
chunk = (chunk + 1) % 2 # this goes 0,1,0,1,... and we +1 above
# now we have the number of characters in each column, so display that
print('\nkey digit and number of characters')
for i, digit in enumerate(key):
print(digit, chars[i])
# but the ordering in the encrypted data is different, so we re-order to
# match that. this uses a bit of a trick in python - if we order a list of
# pairs (a,b) then is it ordered by the first thing in the list (the key
# digit) here. so we order by the key digit, but also re-arrange the
# columns sizes.
digitsandchars = [(digit, chars[i]) for i, digit in enumerate(key)]
print('\nbefore sorting', digitsandchars)
digitsandchars = sorted(digitsandchars)
print('after sorting', digitsandchars)
# now that we have the columns sizes in the right order we can cut up the
# text into the columns
columns = [''] * n
for i in range(n):
digit, nchars = digitsandchars[i]
columns[i] = ctext[:nchars]
ctext = ctext[nchars:]
print('digit', digit, 'column', columns[i])
# now switch the columns back to the order they were originally
ordered = [columns[int(key[i])-1] for i in range(5)]
print('\nordered columns', ordered)
# and finally we can decode by doing the same process as before - we pick
# off 1 or 2 characters from each column until we have nothing left.
print('\ndecode')
icolumn = 0
remaining = l
chunk = 0
while remaining > 0:
column = ordered[icolumn]
k = min(chunk+1, remaining)
print(column[:k], end='') # print the first k characters
remaining -= k
ordered[icolumn] = column[k:] # remove the printed characters
icolumn = (icolumn + 1) % n
chunk = (chunk + 1) % 2
print()
d29yZHMgPSBbJ0hFVEVBTVQnLCdUT1dJTU8nLCdOTlNFSk4nLCdEVE9TRUInLCdSRVJSSE8nLCdPSVNTTUknLCdVUk5PUkknLCdTSElST1InXQoKY3RleHQgPSAnJy5qb2luKHdvcmRzKQpsID0gbGVuKGN0ZXh0KQpwcmludCgnXG50b3RhbCBjaGFycycsIGwpCgprZXkgPSAnNzQ1NjMyMScKbiA9IGxlbihrZXkpCnByaW50KCdcbmtleSBsZW5ndGgnLCBuKQoKIyBoZXJlIHdlIGRvIGV4YWN0bHkgdGhlIHNhbWUgYXMgd2hhdCB5b3UgZGlkIHRvIGVuY29kZSwgZXhjZXB0IHdlIGp1c3QKIyBjb3VudCB0aGUgbGV0dGVycy4gIHNvIGNoYXJzW3hdIGlzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBjb2x1bW4geCwKIyB3aGljaCBzdGFydHMgYXQgMCBhbmQgaXMgYWRkZWQgMSBvciAyIG9uIGVhY2ggbGluZS4KY2hhcnMgPSBbMF0gKiBuCnJlbWFpbmluZyA9IGwKaWNoYXIgPSAwCmNodW5rID0gMAp3aGlsZSByZW1haW5pbmcgPiAwOgogICAgayA9IG1pbihjaHVuaysxLCByZW1haW5pbmcpCiAgICBjaGFyc1tpY2hhcl0gKz0gawogICAgcmVtYWluaW5nIC09IGsKICAgIGljaGFyID0gKGljaGFyICsgMSkgJSBuICAjIHRoaXMgaW5kZXhlcyB0aGUgY29sdW1ucyAwLi5uLTEsMC4ubi0xLC4uLgogICAgY2h1bmsgPSAoY2h1bmsgKyAxKSAlIDIgICMgdGhpcyBnb2VzIDAsMSwwLDEsLi4uIGFuZCB3ZSArMSBhYm92ZQoKIyBub3cgd2UgaGF2ZSB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gZWFjaCBjb2x1bW4sIHNvIGRpc3BsYXkgdGhhdApwcmludCgnXG5rZXkgZGlnaXQgYW5kIG51bWJlciBvZiBjaGFyYWN0ZXJzJykKZm9yIGksIGRpZ2l0IGluIGVudW1lcmF0ZShrZXkpOgogICAgcHJpbnQoZGlnaXQsIGNoYXJzW2ldKQoKIyBidXQgdGhlIG9yZGVyaW5nIGluIHRoZSBlbmNyeXB0ZWQgZGF0YSBpcyBkaWZmZXJlbnQsIHNvIHdlIHJlLW9yZGVyIHRvCiMgbWF0Y2ggdGhhdC4gIHRoaXMgdXNlcyBhIGJpdCBvZiBhIHRyaWNrIGluIHB5dGhvbiAtIGlmIHdlIG9yZGVyIGEgbGlzdCBvZgojIHBhaXJzIChhLGIpIHRoZW4gaXMgaXQgb3JkZXJlZCBieSB0aGUgZmlyc3QgdGhpbmcgaW4gdGhlIGxpc3QgKHRoZSBrZXkgCiMgZGlnaXQpIGhlcmUuICBzbyB3ZSBvcmRlciBieSB0aGUga2V5IGRpZ2l0LCBidXQgYWxzbyByZS1hcnJhbmdlIHRoZQojIGNvbHVtbnMgc2l6ZXMuCmRpZ2l0c2FuZGNoYXJzID0gWyhkaWdpdCwgY2hhcnNbaV0pIGZvciBpLCBkaWdpdCBpbiBlbnVtZXJhdGUoa2V5KV0KcHJpbnQoJ1xuYmVmb3JlIHNvcnRpbmcnLCBkaWdpdHNhbmRjaGFycykKZGlnaXRzYW5kY2hhcnMgPSBzb3J0ZWQoZGlnaXRzYW5kY2hhcnMpCnByaW50KCdhZnRlciBzb3J0aW5nJywgZGlnaXRzYW5kY2hhcnMpCgojIG5vdyB0aGF0IHdlIGhhdmUgdGhlIGNvbHVtbnMgc2l6ZXMgaW4gdGhlIHJpZ2h0IG9yZGVyIHdlIGNhbiBjdXQgdXAgdGhlCiMgdGV4dCBpbnRvIHRoZSBjb2x1bW5zCmNvbHVtbnMgPSBbJyddICogbgpmb3IgaSBpbiByYW5nZShuKToKICAgIGRpZ2l0LCBuY2hhcnMgPSBkaWdpdHNhbmRjaGFyc1tpXQogICAgY29sdW1uc1tpXSA9IGN0ZXh0WzpuY2hhcnNdCiAgICBjdGV4dCA9IGN0ZXh0W25jaGFyczpdCiAgICBwcmludCgnZGlnaXQnLCBkaWdpdCwgJ2NvbHVtbicsIGNvbHVtbnNbaV0pCgojIG5vdyBzd2l0Y2ggdGhlIGNvbHVtbnMgYmFjayB0byB0aGUgb3JkZXIgdGhleSB3ZXJlIG9yaWdpbmFsbHkKb3JkZXJlZCA9IFtjb2x1bW5zW2ludChrZXlbaV0pLTFdIGZvciBpIGluIHJhbmdlKDUpXQpwcmludCgnXG5vcmRlcmVkIGNvbHVtbnMnLCBvcmRlcmVkKQoKIyBhbmQgZmluYWxseSB3ZSBjYW4gZGVjb2RlIGJ5IGRvaW5nIHRoZSBzYW1lIHByb2Nlc3MgYXMgYmVmb3JlIC0gd2UgcGljawojIG9mZiAxIG9yIDIgY2hhcmFjdGVycyBmcm9tIGVhY2ggY29sdW1uIHVudGlsIHdlIGhhdmUgbm90aGluZyBsZWZ0LgpwcmludCgnXG5kZWNvZGUnKQppY29sdW1uID0gMApyZW1haW5pbmcgPSBsCmNodW5rID0gMAp3aGlsZSByZW1haW5pbmcgPiAwOgogICAgY29sdW1uID0gb3JkZXJlZFtpY29sdW1uXQogICAgayA9IG1pbihjaHVuaysxLCByZW1haW5pbmcpCiAgICBwcmludChjb2x1bW5bOmtdLCBlbmQ9JycpICAjIHByaW50IHRoZSBmaXJzdCBrIGNoYXJhY3RlcnMKICAgIHJlbWFpbmluZyAtPSBrCiAgICBvcmRlcmVkW2ljb2x1bW5dID0gY29sdW1uW2s6XSAgIyByZW1vdmUgdGhlIHByaW50ZWQgY2hhcmFjdGVycwogICAgaWNvbHVtbiA9IChpY29sdW1uICsgMSkgJSBuCiAgICBjaHVuayA9IChjaHVuayArIDEpICUgMgpwcmludCgpCgo=
total chars 49
key length 7
key digit and number of characters
7 7
4 8
5 7
6 8
3 7
2 6
1 6
before sorting [('7', 7), ('4', 8), ('5', 7), ('6', 8), ('3', 7), ('2', 6), ('1', 6)]
after sorting [('1', 6), ('2', 6), ('3', 7), ('4', 8), ('5', 7), ('6', 8), ('7', 7)]
digit 1 column HETEAM
digit 2 column TTOWIM
digit 3 column ONNSEJN
digit 4 column DTOSEBRE
digit 5 column RRHOOIS
digit 6 column SMIURNOR
digit 7 column ISHIROR
ordered columns ['ISHIROR', 'DTOSEBRE', 'RRHOOIS', 'SMIURNOR', 'ONNSEJN']
decode
IDTRSMO
Traceback (most recent call last):
File "prog.py", line 60, in <module>
column = ordered[icolumn]
IndexError: list index out of range