质数
质数是大于1且只有1和它本身两个因数的整数。
以下列出一些质数(注意,1不被看做质数):
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 ......无穷无尽。
质数有无穷多个,这意味着没有“最大”质数。它们只会越来越大,就像普通数字一样。 RSA加密法的密钥使用非常大的质数。因此, 密钥太多而不能暴力破译。
但这些都是小数字。我们的RSA程序通常使用的质数都有上百个数位:
112 829 754 900 439 506 175 719 191 782 841 802 172 556 768 253 593 054 977 186 235 584 979 780 304 652 423 405 148 425 447 063 090 165 759 070 742 102 132 335 103 295 947 000 718 386 333 756 395 799 633 478 227 612 244 071 875 721 006 813 307 628 061 280 861 610 153 485 352 017 238 548 269 452 852 733 818 231 045 171 038 838 387 845 888 589 411 762 622 041 204 120 706 150 518 465 720 862 068 595 814 264 819
以上数字很大,我猜你甚至不会去看它里面有没有输入错误。
如何判断一个数是不是质数?
1)最直观的方法,根据定义,因为质数除了1和本身之外没有其他约数,所以判断n是否为质数,根据定义直接判断从2到n-1是否存在n的约数即可。
2)这种方法,明显存在效率极低的问题。对于每个数n,其实并不需要从2判断到n-1,我们知道,一个数若可以进行因数分解,那么分解时得到的两个数一定是一个小于等于sqrt(n),一个大于等于sqrt(n),据此,上述代码中并不需要遍历到n-1,遍历到sqrt(n)即可,因为若sqrt(n)左侧找不到约数,那么右侧也一定找不到约数。
3)其实质数还有一个特点,就是它总是等于 6x-1 或者 6x+1,其中 x 是大于等于1的自然数。如何论证这个结论呢,其实不难。首先 6x 肯定不是质数,因为它能被 6 整除;其次 6x+2 肯定也不是质数,因为它还能被2整除;依次类推,6x+3 肯定能被 3 整除;6x+4 肯定能被 2 整除。那么,就只有 6x+1 和 6x+5 (即等同于6x-1) 可能是质数了。所以循环的步长可以设为 6,然后每次只判断 6 两侧的数即可。
但是如果像 1 070 595 206 942 983这种数字呢?如果你用这三种方法来判断,可能需要数秒才能判断它是不是质数。如果某个数字有数百个数位(就像RSA程序的质数那样), 将要超过一万亿年才能判断这一个数字是不是质数。
Rabin-Miller
拉宾米勒质数测试 The Rabin-Miller Primality Test)的算法可以判断数百位的数字是不是质数。
费马小定理:N为任意正整数,P为素数且N不能被P整除(显然N和P互质),则(N^(P-1)) % P == 1。
所以如果N小于P,则N和P肯定互质。那么随机抽取N < P,如果(N^(P-1)) % P != 1,则P为合数如果等于1,则P有可能为质数;而且N取的组数越多,结果越精确
import random
def rabinMiller(num):
s = num - 1
t = 0
while s%2 == 0:
s //= 2
t += 1
for trials in range(5):
a = random.randrange(2,num-1)
v = pow(a,s,num)
if v!=1:
i = 0
while v!=(num-1):
if i == t-1:
return False
else:
i += 1
v = (v**2)%num
return True
def isPrime(num):
if num<2:
return False
lowPrimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
if num in lowPrimes:
return True
for prime in lowPrimes:
if num % prime==0:
return False
return rabinMiller(num)
def generateLargePrime(keysize=1024):
while True:
num = random.randrange(2**(keysize-1),2**keysize)
if isPrime(num):
return num
if __name__ == '__main__':
a=generateLargePrime()
print(a)