质数判断 查表法和计算法结合提高效率 (不能因式分解)
1. 梅森质数(Mersenne Prime)
梅森质数是形式为 2p−12p−1 的质数(pp 为质数),例如:
- 22−1=322−1=3(质数);
- 23−1=723−1=7(质数);
- 25−1=3125−1=31(质数)。
梅森质数的特点是容易验证(使用卢卡斯-莱默测试,Lucas-Lehmer Test),因此成为寻找大质数的主要目标。
2. GIMPS项目(分布式计算的典范)
GIMPS(Great Internet Mersenne Prime Search,伟大的互联网梅森质数搜索)是全球最大的分布式计算项目,由成千上万的志愿者用空闲计算机运行软件,寻找梅森质数。
- 成果:自1996年以来,GIMPS已发现17个梅森质数,其中目前已知的最大质数是 282589933−1282589933−1(2018年发现,有24862048位数字)。
- 意义:
- 推动分布式计算技术(如并行计算、负载均衡)的发展;
- 为密码学提供更安全的密钥材料(更大的质数意味着更难分解,更安全的加密)。
//若需频繁调用,可预生成小质数表,先尝试整除质数再遍历。
//RSA 哈希表优化到随机数生成到分布式计算
int is_prime(int n) {
const int prime[]={//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,
// 0-100(25个)
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-200(21个)
101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199
//201-300(16个)
211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293
//301-400(16个)
307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397
//401-500(17个)
401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499
//501-600(14个)
503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599
//601-700(16个)
601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691
//701-800(14个)
701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797
//801-900(15个)
809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887
//901-1000(14个)
907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997
};
// if (n <= 1) return 0; // 小于等于1不是质数
// if (n == 2) return 1; // 2是质数 唯一偶质数
// if (n % 2 == 0) return 0; // 排除偶数(除2外)
if (n <= 1) return 0;
if (n == 2 || n == 3) return 1;
if (n % 2 == 0 || n % 3 == 0) return 0;
// 查表法:适用于小范围数字
for (int i = 0; i < sizeof(prime)/sizeof(prime[0]); i++) {
if (n == prime[i]) return 1;
if (n %prime[i]==0) break;
if (n < prime[i]) break; // 数组有序,提前终止
}
int limit = (int)sqrt(n) + 1; // 优化:只需检查到 √n
// for (int i = 3; i <= limit; i += 2) { // 跳过偶数
for (int i = 5; i * i <= n; i += 6) { // 从5开始,步长为6
if (n % i == 0) return 0;
if (n % (i + 2) == 0) return 0;
}
return 1;
}