好的,所以我一直在从事这个项目只是出于教育目的,对密码的安全性并不感兴趣。密码通过首先为每个ascii字符(存储在ord函数中,即0-256)生成具有不同位置的随机网格,然后将消息加密到网格上的坐标中。使用此代码生成网格时会出现问题:
import random
from pickle import load, dump
class Encryptor():
def __init__(self):
#array=[]
#for i in range(129):
# array.append(False)
array_full=[]
for i in range(16):
array_full.append([False]*16)
self.letterkeys = range(256)
self.coords=[]
self.key=False
self.grid=array_full
def gen_key(self):#Generate the Key
prev_grid=self.grid
full=False
while not full:
try:
coord=(random.randint(0, 16),random.randint(0, 16))
val=random.choice(self.letterkeys)
if coord not in self.coords:
del self.letterkeys[self.letterkeys.index(val)]
self.grid[coord[0]][coord[1]] = val
self.coords.append(coord)
except:
full=True
self.key=self.grid
self.grid=prev_grid
def dump_key(self,name):
file=open(name,'w')
dump(self.key,file)
file.close()
def encrypt(self,message):
pass
encrypt=Encryptor()
encrypt.gen_key()
encrypt.dump_key('example.key')
print encrypt.key
给定的输出应该只是一个完整的网格,所有ascii代码都没有更多的错误,但我得到这样的东西:
[[False, 151, 204, False, 112, 47, 58, False, 123, 126, 255, 111, 133, 39, 15, 14, 188, 88, 242, 241, 114, 195, 117, 105, 106, 25, 70, 187, False#etc.
所以由于某种原因,填充网格之前字母键已经用完了,所以我相信它可能是一个数组大小的问题。这是一个正确的假设,如果不是我做错了吗?
请注意: 我不想使用像numpy这样的更高级别的模块以及让生活更轻松的事情,因为我希望这个项目作为一种学习体验培养我对python的了解。
答案 0 :(得分:1)
class Encryptor():
def __init__(self):
array=[]
for i in range(129):
array.append(False)
array_full=[]
for i in range(129):
array_full.append(array)
self.letterkeys = range(257)
self.grid=array_full
你的第一个循环是建立一个[False,False,False,...]
的列表你的第二个循环是而不是建立一个你想要的列表列表,它正在建立一个重复列表的列表。
这在文本中并不是一个非常明显的区别,但请看这个:
>>> list1 = [False, False] # Two items in a list
>>> list2 = [] # An empty list
>>> list2.append(list1) # Make a 2x2 grid
>>> list2.append(list1)
>>> list2
[[False, False], [False, False]] # Looks fine
>>> list1[0] = True # Change only one thing in list1
>>> list2
[[True, False], [True, False]] # Oh, two things have changed!
>>>
这似乎与您的其他代码相关,后者试图说:
网格将无法满员。无处可去。
但是当你打印它时看起来几乎已经满了,因为上面的内容 - 当你设置一个值时,它会在列表的每个副本中发生变化。
您随机选择要填充的网格位置这一事实是另一个组合错误 - 因为您可以填充网格[0] [1]或网格[1] [1]并且值会在所有副本中发生变化,这意味着您的测试if coord not in self.coords:
这应该阻止你两次覆盖同一个地方实际上并没有这样做,因为你最终只是使用不同的坐标覆盖同一个地方两次。
(除此之外,你怎么想象你可以通过仅使用(0-127,0-127)的坐标将256个数字映射到16,000+项目网格(0-256,0-256),并使其满之后?)
注释
[False] * 128
file
已经是Python中的一个名称,将它用作打开文件的名称是不好的形式def gen_key(self): #Generate the Key
import string
和string.ascii_letters
或string.printable
random
模块,random.shuffle
用于随机播放列表修改强>
提出答案:抛弃你的代码,你不需要pickle,你不需要一个类,你不需要庞大的列表,你不需要在Python中循环,使用模块随Python一起提供,你只需要将26个字母和一些标点符号混合成不同的顺序,然后用它来编码一些文本:
import string, random
plain = string.printable
tmp = list(string.printable)
random.shuffle(tmp)
shuffled = ''.join(tmp)
trans_table = string.maketrans(plain, shuffled)
print string.translate("some text here", trans_table)
答案 1 :(得分:1)
所需的更改包括:删除以下评论中显示的部分,并将array_full
的生成更改为如下所示。
class Encryptor():
def __init__(self):
#array=[]
#for i in range(129):
# array.append(False)
array_full=[]
for i in range(129):
array_full.append()
for j in range(129):
array_full[i].append(False) #edited out: array_full[i] = [False]*129
self.letterkeys = range(257)
self.coords=[]
self.key=False
self.grid=array_full
正如TessellatingHeckler所指出的,当您使用self.grid[coord[0]][coord[1]] = val
更新单元格的值时,它正在更新以及覆盖索引为{{的坐标的先前值每行1}}。用一个简单的3x3矩阵示例说明。
coord[1]
这将显示在(1,2)处更改元素的值将更改所有行中第二个元素的值(因为您使用>>> a = [0]*3
>>> b = []
>>> for i in range(3):
... b.append(a)
>>> print "\n".join(str(k) for k in b)
[0,0,0]
[0,0,0]
[0,0,0]
>>> b[1][2] = 1
>>> print "\n".join(str(k) for k in b)
[0,0,1]
[0,0,1]
[0,0,1]
的相同副本生成了矩阵)
此外,您的网格有129x129 = 16641个单元格。 您正在更新257个单元格(范围(257))。
因此,很明显会有大量的可用空间。
编辑:array[]
将遇到上述相同的问题。您可以尝试使用嵌套循环(如编辑后)。