繁体   English   中英

二维数组用于python中的加密

[英]two dimensional array for encryption in python

我想让用户制作任何必要大小的表。 首先,他将输入行数和列数,然后为每一列和每一行输入一对数字,然后输入其余单元格中的数据。 这是一个例子:

row\column|  23  |  54  |  34  |  75
-------------------------------------
   65     |  AM  |   h  |   9  |  C
-------------------------------------
   78     |  56  |   in |   13 |  ok

因此,基本上,在输入所有信息之后,他应该能够说7834并得到13,反之亦然(例如,输入9C并得到65346575)。

我尝试了一下,但我理解为什么它不起作用,但这是我唯一的想法。

nc = int(raw_input('Input number of columns: '))
nr = int(raw_input('Input number of rows: '))

table = [[raw_input('Input two digits for each column: ') for i in range(2, nc)] for i in range(1)]
table = [[raw_input('Input two digits for each row: ') for i in range(1)] for i in range(2, nr)]
table = [[raw_input('Input data: ') for i in range(2, nc)] for i in range(2, nr)]

任何帮助表示赞赏。

不会那样工作。

实际上,我有点说谎。 那种方式会起作用(我对您编写的生成器有麻烦):

>>> table = [[raw_input('Input data: ') for i in range(1, nc+1)] for i in         range(1, nr+1)]
Input data: 1
Input data: 2
Input data: 3
Input data: 4
Input data: 5
Input data: 6 
Input data: 7 
Input data: 8
Input data: 9
>>> table
[['1', '2', '3'], ['4', '5', '6'], ['7', '8', '9']]

但这就是您一开始所要求的-您似乎希望最终用户能够输入列标题和行标题,然后填充数据。

要是我们:

table = [[raw_input('Input data: {},{} '.format(a,b)) for a in range(0, nc)] for b in range(0, nr)]

那么我们可以得到:

Input data: 0,0 None
Input data: 1,0 1
Input data: 2,0 2
Input data: 0,1 a
Input data: 1,1 Ted
Input data: 2,1 Fred
Input data: 0,2 b
Input data: 1,2 3.214
Input data: 2,2 Copy
>>> table
[['None', '1', '2'], ['a', 'Ted', 'Fred'], ['b', '3.214', 'Copy']]

现在,该方案的混乱之处在于,要在“网格”中找到坐标,您必须读取每个列标题并获取其位置,然后读取每个行标题以获取位置。 那么你也能 :

值=网格[r] [c]

现在,进行反向操作变得更加困难-您必须阅读每个单元格,才能获取行标题和列标题。

哦,我们还没有进行任何错误检查,以确保您不会输入相同的两行或标题,这将完全打击您的计划。 您将需要它。

此外,填写该网格还需要进行大量工作。

剩下的就是我在没有发电机的情况下使用它,并且犯了一些教育上的错误。

如果要使用列表列表:

row = [None for i in range(0,nc+1)]
grid = [row for i in range(0,nr+1)]

然后,这会为您提供一个列表,其中填充了“无”。

>>> grid
[[None, None, None, None], [None, None, None, None], [None, None, None, None], [None, None, None, None]]

好的,所以放入列标题:

>>> for ch in range (1,nc+1):
...     grid[0][ch] = raw_input("Header, Column {}".format(ch))
...
Header, Column 111
Header, Column 222
Header, Column 333
>>> grid
[[None, '11', '22', '33'], [None, '11', '22', '33'], [None, '11', '22', '33'], [None, '11', '22', '33']]

呵呵,那为什么不行呢?

>>> grid[0][3]="steve"
>>> grid
[[None, '11', '22', 'steve'], [None, '11', '22', 'steve'], [None, '11', '22', 'steve'], [None, '11', '22', 'steve']]

哦耶。

臭虫

import copy
row = [None for i in range(0,nc+1)]
grid = [copy.deepcopy(row) for i in range(0,nr+1)]
>>> for ch in range (1,nc+1):
...     grid[0][ch] = raw_input("Header, Column {}: ".format(ch))
...
Header, Column 1: 11
Header, Column 2: 22
Header, Column 3: 33
>>> grid
[[None, '11', '22', '33'], [None, 5, None, None], [None, None, None, None], [None, None, None, None]]

(忽略5,那是我正在测试的)

然后是行:

>>> for rh in range(1,nr+1):
...     grid[rh][0] = raw_input("Row Header: {} ".format(rh))
...
Row Header: 1 11
Row Header: 2 22
Row Header: 3 33
>>> grid
[[None, '11', '22', '33'], ['11', 5, None, None], ['22', None, None, None], ['33', None, None, None]]

因此,现在您用数据填充数据(作为练习,因为它很明显,因此保留)。

我自由地将所有整数保留为字符串,因为您表现出将它们连接在一起的趋势。

如果您真的想要一个可转置的2D数组,那么最痛苦(且功能非常强大)的解决方案是使用numpy数组。 如果尚未安装numpy,则必须安装,但是由于您没有为扩展库指定任何限制,因此我认为此解决方案是可以接受的。

数组索引从0开始,仅接受整数。 有一些方法可以使数组具有自定义索引,例如23, 54, 34, 75而不是0, 1, 2, 3 如果您决定numpy.array并重写其许多方法, 则可能比预期的要复杂得多

相反,我提供了一种创建包装器类的解决方案,该包装器类可以处理您的自定义索引,但不能切片(无论如何,这可能对您来说都是废话)。 在后台,当您请求“ 6523”时,它将把它分成2位数字的字符串“ 65”和“ 23”,然后在行/列列表中查找它们的位置。 在这种情况下,它将是(0,0)。 现在,您可以将该索引用于数组以获取所需的元素。 查找元素的索引的方法相反。 我们绝不会直接与数组结构进行交互,因此无需重写其任何方法。

import numpy as np

class CustomIndexTable:
    def __init__(self, rows, columns, elements):
        self.rows = rows
        self.columns = columns
        self.data = np.array(elements, dtype=object)
        self.data = self.data.reshape((len(rows), len(columns)))

    def __getitem__(self, index):
        x, y = index[:2], index[2:]
        return self.data[self.rows.index(x),self.columns.index(y)]

    def __setitem__(self, index, element):
        x, y = index[:2], index[2:]
        self.data[self.rows.index(x),self.columns.index(y)] = element

    def _where(self, element):
        x, y = np.where(self.data == element)
        return self.rows[x] + self.columns[y]

    def transpose(self):
        self.rows, self.columns = self.columns, self.rows
        self.data = self.data.T

    def where(self, sequence):
        elements = []
        start = 0
        for end in xrange(1, len(sequence)+1):
            if sequence[start:end] in self.data:
                elements.append(sequence[start:end])
                start = end
        return ''.join(self._where(e) for e in elements)

def input_matrix_data(text):
    return raw_input(text).split()

col_indices = input_matrix_data("Column indices: ")
row_indices = input_matrix_data("Row indices: ")
data = input_matrix_data("All data, sorted by row: ")

table = CustomIndexTable(row_indices, col_indices, data)

评论

您不希望用户在输入新元素时重复表索引,例如对(65,23)和(65,54)重复65。 您可以简单地要求用户一次输入列索引和行索引,稍后我们将构建各个表的坐标。 对于数据,让用户一次输入所有内容,就像读一本书中的几行一样,即从左到右逐行。 对于所有输入,用户应使用空格分隔各个成员。 例如,当输入列索引时,他应该写

23 54 34 75

和数据

AM h 9 C 56 in 13 ok

将数据保存在一维列表中后,我们可以将它们放入数组中,并以每行指定的列数将其重塑为二维。

该类的结构对功能进行了一些假设,这些假设是您的问题所隐含的。

  • 所有行/列标签都是2位整数(为方便起见,为字符串格式)。
  • 没有两个或更多个具有相同名称的表/行/列元素,因为在这种情况下list.index()numpy.where()可能不会像您期望的那样表现。 这种假设是有道理的,因为使用表似乎是为了进行加密/解密,因此,每个元素都应该唯一地映射到另一个元素。
  • 在搜索元素序列的索引时,它假定表中没有元素是另一个元素的前缀,即“ 9”和“ 97”。

用法

构建完表格后,您可以查看数据(不要直接编辑数组!),

>>> table.data
array([['AM', 'h', '9', 'C'],
       ['56', 'in', '13', 'ok']], dtype=object)

访问特定元素,

>>> table['7834']
'13'

为一个元素设置一个新值,

>>> table['7834']  = 'B'
>>> table['7834']
'B'

找到元素所在的位置,

>>> table.where('9')   # this should work equally well for '9C'
'6534'

或永久转置数组。

>>> table.transpose()
>>> table.where('9')
'3465'

最后,您可以在满足您的需要时向此类添加更多方法,例如,在创建表之后添加/删除整行元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM