带列表的 3x1 矩阵乘法
3x1 Matrix Multiplication with lists
这是对 Hill Cipher 的尝试,到目前为止一直很好,直到第 2 个和第 3 个 trigram 相乘。我真的不明白我的错误在哪里。
基本上我要做的是列表乘法。
使用这段代码我创建了一个列表
key=[k[x:x+3] for x in xrange(0, len(k), 3)]
message=[m[x:x+1] for x in xrange(0, len(m), 1)]
key=[[16, 4, 11], [8, 6, 18], [15, 19, 15]]
message=[[0], [12], [8], [6], [15], [2], [15], [13], [3], [21], [2], [20], [15], [18], [8]]
我的目标是将 key list
中的每个子列表或列乘以 message list
中的前三个列表
更新:
我按照建议做了一个嵌套循环,我也把消息列表分成了块,但我仍然不能让它工作。
嵌套循环
result = [[0,],
[0,],
[0],]
#Divide the matrizm into chunks
n = 3
chunks = (matrizm[x:x+n] for x in range(0,len(matrizm), n))
#Matrix multiplication
for triagram in chunks:
# iterate through rows of X
for i in range(len(matrizk)):
# iterate through columns of Y
for j in range(len(triagram[1])):
# iterate through rows of Y
for k in range(len(matrizk)):
result[i][j] += matrizk[i][k] * triagram[k][j]
使用我当前的代码,我只能将前 3 个三角字母相乘,顺便说一句,结果不正确。
我的问题是,有了这两个列表,我如何将前 3 个三字相乘,然后再乘以另外 3 个,依此类推,直到 matrizk 列表结束
matrizk = [[16, 4, 11], [8, 6, 18], [15, 19, 15]]
matrizk = [[0], [12], [8], [6], [15], [2], [15], [13], [3], [21], [2], [20], [15], [18], [3]]
答案假定 Python 2.7x
数据:
key=[[16, 4, 11], [8, 6, 18], [15, 19, 15]]
message=[[0], [12], [8], [6], [15], [2], [15], [13], [3], [21], [2], [20], [15], [18], [8]]
似乎使事情复杂化的一件事是 message
是一个列表的列表,为了使事情变得更容易,它需要在某些时候被压平。
我将使用 itertools
recipe to get chunks of the message because I'm going to use a generator to flatten the message. There are other ways to flatten a list found in the answers to: How do you split a list into evenly sized chunks in Python?
import itertools
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return itertools.izip_longest(fillvalue=fillvalue, *args)
# flatten the message [[1],[2]] -> [1,2]
message = (item for thing in message for item in thing)
zip
是另一个有用的函数,它类似于一个转置:
>>> zip([1,2],[3,4])
[(1, 3), (2, 4)]
>>>
现在我们将对密钥和消息的每个 3 项块进行矩阵乘法。
for group in grouper(message, n):
# matrix multiplication
for row in key:
sum_prod = 0
for a, b in zip(group, row):
sum_prod += a*b
#print(group, row, sum_prod, sum_prod % 26)
result.append(sum_prod)
#result.append(sum_prod % 26)
这是对 Hill Cipher 的尝试,到目前为止一直很好,直到第 2 个和第 3 个 trigram 相乘。我真的不明白我的错误在哪里。 基本上我要做的是列表乘法。
使用这段代码我创建了一个列表
key=[k[x:x+3] for x in xrange(0, len(k), 3)]
message=[m[x:x+1] for x in xrange(0, len(m), 1)]
key=[[16, 4, 11], [8, 6, 18], [15, 19, 15]]
message=[[0], [12], [8], [6], [15], [2], [15], [13], [3], [21], [2], [20], [15], [18], [8]]
我的目标是将 key list
中的每个子列表或列乘以 message list
更新: 我按照建议做了一个嵌套循环,我也把消息列表分成了块,但我仍然不能让它工作。
嵌套循环
result = [[0,],
[0,],
[0],]
#Divide the matrizm into chunks
n = 3
chunks = (matrizm[x:x+n] for x in range(0,len(matrizm), n))
#Matrix multiplication
for triagram in chunks:
# iterate through rows of X
for i in range(len(matrizk)):
# iterate through columns of Y
for j in range(len(triagram[1])):
# iterate through rows of Y
for k in range(len(matrizk)):
result[i][j] += matrizk[i][k] * triagram[k][j]
使用我当前的代码,我只能将前 3 个三角字母相乘,顺便说一句,结果不正确。
我的问题是,有了这两个列表,我如何将前 3 个三字相乘,然后再乘以另外 3 个,依此类推,直到 matrizk 列表结束
matrizk = [[16, 4, 11], [8, 6, 18], [15, 19, 15]]
matrizk = [[0], [12], [8], [6], [15], [2], [15], [13], [3], [21], [2], [20], [15], [18], [3]]
答案假定 Python 2.7x
数据:
key=[[16, 4, 11], [8, 6, 18], [15, 19, 15]]
message=[[0], [12], [8], [6], [15], [2], [15], [13], [3], [21], [2], [20], [15], [18], [8]]
似乎使事情复杂化的一件事是 message
是一个列表的列表,为了使事情变得更容易,它需要在某些时候被压平。
我将使用 itertools
recipe to get chunks of the message because I'm going to use a generator to flatten the message. There are other ways to flatten a list found in the answers to: How do you split a list into evenly sized chunks in Python?
import itertools
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return itertools.izip_longest(fillvalue=fillvalue, *args)
# flatten the message [[1],[2]] -> [1,2]
message = (item for thing in message for item in thing)
zip
是另一个有用的函数,它类似于一个转置:
>>> zip([1,2],[3,4])
[(1, 3), (2, 4)]
>>>
现在我们将对密钥和消息的每个 3 项块进行矩阵乘法。
for group in grouper(message, n):
# matrix multiplication
for row in key:
sum_prod = 0
for a, b in zip(group, row):
sum_prod += a*b
#print(group, row, sum_prod, sum_prod % 26)
result.append(sum_prod)
#result.append(sum_prod % 26)