python生成一组二进制1024位和512位数的大质数对
前些天同学求助: 用python生成一组二进制1024位与512位数的大素数对,要求1024位的质数减一后可以整除512位数,经过两天鏖战后成功,在这里总结一下思路与代码。简单来讲,生成质数对首先要生成质数,之后再成对就ok了,下面分成两部分说明。
一. 生成大素数
解决这个问题首先需要生成大素数,一个二进制的1024位数大概相当于300位十进制位数,运用穷举法最多可能跑到1亿(9位十进制数)这种单位,300位的大数用我的电脑是不可能跑出来的,所以只能更换算法。
经过查阅,随着数的增大,质数的数量其实是在大幅增多的,而随机生成一个1024位二进制奇数很容易,只要能判断出来这个数是否是质数就可以了,如果不成立的话,在附近不断+2应该很快就能找到了一个质数。根据这个想法,生成大素数的算法分3部:
1.生成伪素数 (把未通过验证的奇数称为伪素数) 2.判断伪素数是否为素数 3.如果不成立,循环判断查找
1.生成伪素数
算法很简单,直接贴代码。
# 其实这个二级制奇数产生代码感觉很冗长,可以优化的很多,欢迎大神指教改进
def proBin(w): # w表示希望产生位数
list = []
list.append(1) #最高位定为1
for i in range(w - 2):
c = randint(0, 1)
list.append(c)
list.append(1)
ls2 = [str(j) for j in list]
ls3 = ''.join(ls2)
b = int(ls3[0])
for i2 in range(len(ls3) - 1):
b = b << 1
b = b + int(ls3[i2 + 1])
d = long(b)
return d
2.判断伪素数是否为素数
这一部分自己的代码编了好几种都跑不理想,想了很久没什么办法,求助度娘,了解素数测试算法后,最终选择了主流的Miller-Rabin检测。这里贴一段百度知道的简介:
Miller-Rabin检测基于概率测试算法,在构建密码安全体系中占有重要的地位
后面会对Miller-Rabin检测原理做深入介绍,如果不关心数学过程,可以跳过这一部分,直接看代码。
Miller-Rabin检测是Fermat算法加入二次探测定理的一种实现,它的理论基础是由Fermat定理引申而来,这里先介绍Fermat定理。
(1)Fermat 定理
Fermat 定理:p是一个质数(非2),a是任何整数(1≤ a≤n-1) ,则
a
p
a^p
ap ≡ a(mod p) 或
a
p
−
1
a^{p-1}
ap−1 ≡ 1(mod p)
a
p
a^p
ap ≡ a(mod p) 为 同余符号,表示
a
p
a^p
ap mod p = a,也可以理解为
a
p
a^p
ap- a可以被 p整除 ,还可以理解为
a
p
a^p
ap与 a 除以p的余数相等, 除以同余式 a ≡ a (mod p)后得常用结论:
a
p
−
1
a^{p -1}
ap−1 ≡ 1(mod p)
根据定理,我们可以随机选取一个数a,然后计算
a