簡體   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