我正在做一个使用RSA算法加密数据的项目,为此,我将一个.wav
文件作为输入,并使用wavfile
进行了读取,我可以应用密钥了(3, 25777),但是当我应用解密密钥(16971,25777)时,给出的输出错误是这样的:
我得到的输出:
[[ 0 -25777]
[ 0 -25777]
[ 0 -25777]
...
[-25777 -25777]
[-15837 -15837]
[ -8621 1]]
我想要的输出:
[[ 0 -1]
[ 2 -1]
[ 2 -3]
...
[-9 -5]
[-2 -2]
[-4 1]]
这仅在数组的解密部分发生,所以我决定将2d数组转换为2d列表。之后,它给了我想要的输出,但是将键应用于列表的所有元素要花费很多时间(16分钟,如果是数组,则为2秒)。我不明白为什么会这样,是否还有其他解决办法?
这是程序的加密和解密部分:
#encryption
for i in range(0, tup[0]): #tup[0] is the no of rows
for j in range(0, tup[1]): #tup[1] is the no of cols
x = data[i][j]
x = ((pow(x,3)) % 25777) #applying the keys
data[i][j] = x #storing back the updated value
#decryption
data= data.tolist() #2d array to list of lists
for i1 in (range(len(data)):
for j1 in (range(len(data[i1]))):
x1 = data[i1][j1]
x1 = (pow(x1, 16971)%25777) #applying the keys
data[i1][j1] = x1
期待提出建议。谢谢。
答案 0 :(得分:4)
pow(x1, 16971)
之类的东西应该让您暂停一下。对于几乎所有的整数x1,这都会产生64位int无法保存的结果。这是numpy给出错误结果的原因,因为numpy在最常见的平台上使用64位或32位整数。这也是纯Python速度慢的原因,因为尽管它可以处理大整数,但代价昂贵。
解决此问题的一种方法是在乘法之间应用模数,从而使数字保持较小并可以通过64位算术轻松处理。
这是一个简单的实现:
def powmod(b, e, m):
b2 = b
res = 1
while e:
if e & 1:
res = (res * b2) % m
b2 = (b2*b2) % m
e >>= 1
return res
例如:
>>> powmod(2000, 16971, 25777)
10087
>>> (2000**16971)%25777
10087
>>> timeit(lambda: powmod(2000, 16971, 25777), number=100)
0.00031936285085976124
>>> timeit(lambda: (2000**16971)%25777, number=100)
0.255017823074013