加密密码不填充网格

时间:2014-03-19 14:06:33

标签: python arrays python-2.7 encryption

好的,所以我一直在从事这个项目只是出于教育目的,对密码的安全性并不感兴趣。密码通过首先为每个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的了解。

2 个答案:

答案 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!
>>> 

这似乎与您的其他代码相关,后者试图说:

  • 构建16,000多个正方形的网格
  • 将256个字母映射到
  • 现在网格应该已满

网格将无法满员。无处可去。

但是当你打印它时看起来几乎已经满了,因为上面的内容 - 当你设置一个值时,它会在列表的每个副本中发生变化。

您随机选择要填充的网格位置这一事实是另一个组合错误 - 因为您可以填充网格[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 stringstring.ascii_lettersstring.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[]将遇到上述相同的问题。您可以尝试使用嵌套循环(如编辑后)。