(以下更新)
从Philip Klein的线性代数文本Coding the Matrix中尝试一个问题。针对所有可能的密钥强制使用密文二进制序列时遇到问题。问题 1.5.1,第 57 页:
一个 11 符号的消息已被加密如下。每个符号由 0 到 26 之间的数字表示(A 映射到 0,B 到 25,空格到 26。)每个数字由 5 位二进制序列表示(0 映射到 00000,26 到 11010)。最后,生成的 55 位序列使用有缺陷的一次性密码器版本进行加密:密钥不是 55 位,而是相同的 5 位随机位序列的 11 个副本。密文为: '10101'、'00100'、'10101'、'01011'、'11001'、'00011'、'01011'、'10101'、'00100'、'11001'、'11010'
目标是找出明文。我遇到的问题是:一,我的解码器函数产生了几个高于 int 26 的 5 位二进制文件。这个函数应该针对每个可能的 5 位二进制序列(密钥)尝试密文二进制序列,直到 int 26,产生每一个可能的明文序列。二,我应该使用伽罗瓦域来确保每个二进制序列保持二进制吗?(1 + 1 = 0 而不是 2)有什么建议吗?我正在尝试通过使用 Klein 的有趣文本来学习线性代数(并提高我有限的 Python 能力)。这是相当困难的......谢谢!
import string
# The Cipher-text
Y = ['10101', '00100', '10101', '01011', '11001', '00011', '01011', '10101', '00100', '11001', '11010']
def trans(bit): # convert the bits into int
x = ''.join(map(str, bit))
return int(x, 2)
def decoder(cipher): # Try the ciphertext against each possible 5 bit sequence (up to 11010)
pos_seq = ["".join("{0:05b}".format(x)) for x in range(27)]
attempt = []
for i in pos_seq:
for j in cipher: # Add ciphertext binary to every possible binary 'key'.
temp = [(int(i[0])+int(j[0])),(int(i[1])+int(j[1])),(int(i[2])+int(j[2])),
(int(i[3])+int(j[3])), (int(i[4])+int(j[4]))]
attempt.append(temp)
for i in range(len(attempt)): # Galois Field, 'two' becomes 'one'
for k in attempt[i]:
if k == 2:
attempt[i][attempt[i].index(k)] = 0
return attempt
new_list = decoder(Y)
decoded = [trans(i) for i in new_list] # translate each 5 digit sequence into int
alph = list(string.ascii_lowercase) # alphabet plus a space
alph.append(' ')
decoded2 = [alph[x] for x in decoded] # Translate int to letter or space
print(decoded2)
更新
感谢曹大方和jason,我将代码编辑如下,发现明文:eve is evil
- 解码器功能范围增加到 32
- (我仍然需要围绕 GF(2) 和 XOR,包括大方使用
x ^ y & mask
) - 使用解码器将返回的列表切成 11 项列表
chunks = [decoded[x:x+11] for x in range(0, len(decoded), 11)]
*因为密文由 11 个“符号”组成
- 将上面列表映射到大方使用的 lambda 函数:
def decode(encoded):
y = []
for i in encoded:
if i < 27:
y.append(i)
return ''.join(map(lambda x: alph[x], y))
for i in chunks:
decoded2 = decode(i)
print(decoded2)