fork download
  1. words = ['HETEAMT','TOWIMO','NNSEJN','DTOSEB','RERRHO','OISSMI','URNORI','SHIROR']
  2.  
  3. ctext = ''.join(words)
  4. l = len(ctext)
  5. print('\ntotal chars', l)
  6.  
  7. key = '7456321'
  8. n = len(key)
  9. print('\nkey length', n)
  10.  
  11. # here we do exactly the same as what you did to encode, except we just
  12. # count the letters. so chars[x] is the number of characters in column x,
  13. # which starts at 0 and is added 1 or 2 on each line.
  14. chars = [0] * n
  15. remaining = l
  16. ichar = 0
  17. chunk = 0
  18. while remaining > 0:
  19. k = min(chunk+1, remaining)
  20. chars[ichar] += k
  21. remaining -= k
  22. ichar = (ichar + 1) % n # this indexes the columns 0..n-1,0..n-1,...
  23. chunk = (chunk + 1) % 2 # this goes 0,1,0,1,... and we +1 above
  24.  
  25. # now we have the number of characters in each column, so display that
  26. print('\nkey digit and number of characters')
  27. for i, digit in enumerate(key):
  28. print(digit, chars[i])
  29.  
  30. # but the ordering in the encrypted data is different, so we re-order to
  31. # match that. this uses a bit of a trick in python - if we order a list of
  32. # pairs (a,b) then is it ordered by the first thing in the list (the key
  33. # digit) here. so we order by the key digit, but also re-arrange the
  34. # columns sizes.
  35. digitsandchars = [(digit, chars[i]) for i, digit in enumerate(key)]
  36. print('\nbefore sorting', digitsandchars)
  37. digitsandchars = sorted(digitsandchars)
  38. print('after sorting', digitsandchars)
  39.  
  40. # now that we have the columns sizes in the right order we can cut up the
  41. # text into the columns
  42. columns = [''] * n
  43. for i in range(n):
  44. digit, nchars = digitsandchars[i]
  45. columns[i] = ctext[:nchars]
  46. ctext = ctext[nchars:]
  47. print('digit', digit, 'column', columns[i])
  48.  
  49. # now switch the columns back to the order they were originally
  50. ordered = [columns[int(key[i])-1] for i in range(n)]
  51. print('\nordered columns', ordered)
  52.  
  53. # and finally we can decode by doing the same process as before - we pick
  54. # off 1 or 2 characters from each column until we have nothing left.
  55. print('\ndecode')
  56. icolumn = 0
  57. remaining = l
  58. chunk = 0
  59. while remaining > 0:
  60. column = ordered[icolumn]
  61. k = min(chunk+1, remaining)
  62. print(column[:k], end='') # print the first k characters
  63. remaining -= k
  64. ordered[icolumn] = column[k:] # remove the printed characters
  65. icolumn = (icolumn + 1) % n
  66. chunk = (chunk + 1) % 2
  67. print()
  68.  
  69.  
Success #stdin #stdout 0.15s 10224KB
stdin
Standard input is empty
stdout
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', 'TTOWIM', 'HETEAM']

decode
IDTRSMOTTHSHORHINNOETISEOURSWIEROBOINEJMAMRRESORN