目录
一、快速幂
二、完整代码
一、快速幂
在求a^b(mod n)的时候如果b的值过大,运算速度会被拉低,且可能存在溢出。
个人理解:快速幂思想:(这里直接举个例子比较直观且容易理解)
例:3^31(mod n) b=31其二进制为11111 等于3^(00001)(mod n) *3^(00010)(mod n) *
3^(00100)(mod n) *3^(01000)(mod n) *3^(10000)(mod n)=3^1(mod n)*3^2(mod n)*3^4(mod n)*3^8(mod n)*3^16(mod n)=3^31(mod n)。不难发现幂依次为1,2,4,8,16,且3^2是3^1的平方,3^4=3^2的平方,即后者的权值是前者的平方,而这个权值能不能乘上去取决于二进制对应的位是不是1。可以首先判断b的最低位是否为1其他的位可以通过右移操作来判断是否为1。a在每次都平方取模即可对应相应的权值。
使用这种方法相较于直接a^b(mod n)的另外一个好处是可以防止数据过大而溢出,因为这种方法它的每次运算都做了取模操作。
def quick(self,a,b):
res=1
while b:
if b&1:
res=(res*a)%self.n
b=b>>1
a=(a*a)%self.n
return res
ps:b不为0就是真。b&1,这里的结果取决于b的最低位,最低位为1就是真,最低位为0就是假,二者做与运算由于1的前面全是0所以它和b的结果的最低位的前面全是0。
二、完整代码
#从底层实现RSA算法的加密和解密,要求加密和解密过程的求幂过程采用快速乘方算法
class rsatest():
def __init__(self,e,d,n):
self.e=e
self.d=d
self.n=n
def quick(self,a,b):
res=1
while b:
if b&1:
res=(res*a)%self.n
b=b>>1
a=(a*a)%self.n
return res
def encrypt(self,p):
return self.quick(p,self.e)
def decrypt(self,c):
return self.quick(c,self.d)
def Evidence(p,e,d,n):
"""
:param p: 明文
:param e: 公钥
:param d: 私钥
:param n: 模
"""
rsa = rsatest(e,d,n)
enc = rsa.encrypt(p)
print(enc)
detext = rsa.decrypt(enc)
print(detext)
Evidence(6789,28693,25417,30997 )
三、测试结果
测试输入:6789 28693 25417 30997
输出:11822 6789
总结
文章可能存在错误,欢迎指出。