破译amsco密码

时间:2013-07-12 18:27:21

标签: math cryptography

我已经成功实施了一个程序,将明文转换为[amsco密码](http://www.thonky.com/kryptos/amsco-cipher/)的密文。但是,我无法获得如何将密文转换为纯文本。我们如何确定将密码转换为纯文本的列长度(或每列的行数)? 例如,如果密文是 EMAAE HUMBA LMNRE AUDSR RTSUN WHAVP TOEMH KITVE DGEUS TEATO SHOSO YHNME EKLAI 并且列密钥是35142,那么在列'1'下,起始字母是E,同一列中的下一行将是MA。列号“1”中的第三行将具有“A”,依此类推。但是,我们如何确定每列的总行数?

感谢。

2 个答案:

答案 0 :(得分:2)

我认为,最简单的方法是编写一个循环来完成编码所做的操作。因此它为每列添加1和2,直到没有字母为止。

这是一个解码文本以显示我的意思的程序(它是用python 3编写的):

words = ['EMAAE', 'HUMBA', 'LMNRE', 'AUDSR', 'RTSUN', 'WHAVP', 
         'TOEMH', 'KITVE', 'DGEUS', 'TEATO', 'SHOSO', 'YHNME', 'EKLAI']

ctext = ''.join(words)
l = len(ctext)
print('\ntotal chars', l)

key = '35142'
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 pair (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(n)]
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()

这是输出:

total chars 65

key length 5

key digit and number of characters
3 13
5 14
1 13
4 13
2 12

before sorting [('3', 13), ('5', 14), ('1', 13), ('4', 13), ('2', 12)]
after sorting [('1', 13), ('2', 12), ('3', 13), ('4', 13), ('5', 14)]
digit 1 column EMAAEHUMBALMN
digit 2 column REAUDSRRTSUN
digit 3 column WHAVPTOEMHKIT
digit 4 column VEDGEUSTEATOS
digit 5 column HOSOYHNMEEKLAI

ordered columns ['WHAVPTOEMHKIT', 'HOSOYHNMEEKLAI', 'EMAAEHUMBALMN', 'VEDGEUSTEATOS', 'REAUDSRRTSUN']

decode
WHOEVERHASMADEAVOYAGEUPTHEHUDSONMUSTREMEMBERTHEKAATSKILLMOUNTAINS

答案 1 :(得分:0)

我测试了安德鲁的代码,它似乎并不适用于所有情况。顺便说一下,我最近在使用Amsco密码,如果你知道密钥,有一种相当简单的解密密文的方法:

  1. 您需要执行的第一步是将密文写入列中,就好像您要对其进行加密一样

  2. 使用此格式,您就可以知道原始纯文本中每列必须包含多少个字母。

  3. 您从密文中知道,前一个或两个字母将出现在标记为1的列中。因此,请找到此列(请记住第1列可能不一定是第一列,具体取决于您的密钥),看一下字母格式,然后加上字母。例如,如果您知道标记为1的列的格式为:

    AB

    C

    DE

    ˚F

  4. 然后你只需要遍历前七个字母,然后按照上面的格式将它们添加到第一列。

    4.对其余列重复此方法,然后完成后,逐行读取字母,以获取原始纯文本。

    我的代码全部正常运行,但正在进行竞争,其中一项任务涉及此密码。我会在两周内完成它。