C语言 设计并实现一种大素数随机生成方法; 实现一种快速判定任意一个大数是不是是素数方法 跪求啊
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言 设计并实现一种大素数随机生成方法; 实现一种快速判定任意一个大数是不是是素数方法 跪求啊相关的知识,希望对你有一定的参考价值。
Rabin -Miller算法是典型的验证一个数字是否为素数的方法。判断素数的方法是Rabin-Miller概率测试,那么他具体的流程是什么呢。假设我们要判断n是不是素数,首先我们必须保证n 是个奇数,那么我们就可以把n 表示为 n = (2^r)*s+1,注意s 也必须是一个奇数。然后我们就要选择一个随机的整数a (1<=a<=n-1),接下来我们就是要判断 a^s=1 (mod n) 或a^((2^j)*s)= -1(mod n)(0<=j如果任意一式成立,我们就说n通过了测试,但是有可能不是素数也能通过测试。所以我们通常要做多次这样的测试,以确保我们得到的是一个素数。(DDS的标准是要经过50次测试)采用Rabin-Miller算法进行验算
首先选择一个代测的随机数p,计算b,b是2整除p-1的次数。然后计算m,使得n=1+(2^b)m。
(1) 选择一个小于p的随机数a。
(2) 设j=0且z=a^m mod p
(3) 如果z=1或z=p-1,那麽p通过测试,可能使素数
(4) 如果j>0且z=1, 那麽p不是素数
(5) 设j=j+1。如果j且z<>p-1,设z=z^2 mod p,然后回到(4)。如果z=p-1,那麽p通过测试,可能为素数。
(6) 如果j=b 且z<>p-1,不是素数
#include<iostream.h>
#include<time.h>
#include<stdlib.h>
//随机数产生器
//产生m~n之间的一个随机数
unsigned long random(unsigned long m,unsigned long n)
srand((unsigned long)time(NULL));
return(unsigned long)(m+rand()%n);
//模幂函数
//返回X^YmodN
long PowMod(long x,long y,long n)
long s,t,u;
s=1;t=x;u=y;
while(u)
if(u&1)s=(s*t)%n;
u>>=1;
t=(t*t)%n;
return s;
//Rabin-Miller素数测试,通过测试返回1,否则返回0。
//n是待测素数。
//注意:通过测试并不一定就是素数,非素数通过测试的概率是1/4
int RabinMillerKnl(unsigned long n)
unsigned long b,m,j,v,i;
//先计算出m、j,使得n-1=m*2^j,其中m是正奇数,j是非负整数
m=n-1;
j=0;
while(!(m&1))
++j;
m>>=1;
//随机取一个b,2<=b<n-1
b=random(2,m);
//计算v=b^mmodn
v=PowMod(b,m,n);
//如果v==1,通过测试
if(v==1)
return 1;
i=1;
//如果v=n-1,通过测试
while(v!=n-1)
//如果i==l,非素数,结束
if(i==j)
return 0;
//v=v^2modn,i=i+1
v=PowMod(v,2,n);
i++;
return 1;
intmain()
unsigned long p;
int count=0;
cout<<"请输入一个数字"<<endl;
cin>>p;
for(int temp=0;temp<5;temp++)
if(RabinMillerKnl(p))
count++;
else
break;
if(count==5)
cout<<"一共通过5次测试,是素数!"<<endl;
else
cout<<"不是素数"<<endl;
return 0;
追问
那产生随机大素数 不是先要产生个大数在判断是否为素数吗 那大数怎么产生 比如我要产生20位内的大数 这怎么弄?
追答代码第一段就是拿来生成随机数的
//随机数产生器
//产生m~n之间的一个随机数
unsigned long random(unsigned long m,unsigned long n)
srand((unsigned long)time(NULL));
return(unsigned long)(m+rand()%n);
我把代码贴进去根本无法运行啊
追答嗯,我没试过,不好意思
第一行改为:
#include<iostream>
第四行加上:
using namespace std;
调试编译好了,没问题了
截图:
大一点的数运行起来有点慢哦!
目前来说大素数随机生成方法是不存在的,这是一个NPC问题,NPC问题世界的七大难题之一,如果你能够解决,就能够拿到100万美金的奖励。但是现在有快速判定任意一个大数是否是素数方法:Miller Rabin算法。
Miller-Rabin算法是目前主流的基于概率的素数测试算法,在构建密码安全体系中占有重要的地位。通过比较各种素数测试算法和对Miller-Rabin算法进行的仔细研究,证明在计算机中构建密码安全体系时, Miller-Rain算法是完成素数测试的最佳选择。通过对Miller-Rabin 算 法底层运算的优化,可以取得较以往实现更好的性能。Miller-Rabin算法是Fermat算法的一个变形改进,它的理论基础是由Fermat定理引申而来。
Fermat 定理: n是一个奇素数,a是任何整数(1≤ a≤n-1) ,则 a^(n-1)≡1(mod n)。
Miller-Rabin 算法的理论基础:如果n是一个奇素数, 将n-1表示成2^s*r的形式(r是奇 数),a 是和n互素的任何整数, 那么ar≡1(mod n) 或者对某个j(0≤j ≤s -1, j∈Z) 等式 a2jr ≡-1(mod n)成立。 这个理论是通过一个事实经由Fermat定理推导而来: n是一个奇素数,则方程x2 ≡ 1 mod n只有±1两个解。
int a, i;
srand(time(NULL));
a = rand();
if (a > 5)
if (a%2==0 || a%3==0 || a%5==0)
printf("%d是个合数\\n", a);
return 0;
else
printf("%d是个素数\\n", a);
return 0;
if (a == 1)
printf("1既不是合数,也不是素数\\n");
for (i=2; i<=a; i++)
if (0 == a%i)
break;
if (a == i)
printf("%d是个素数\\n", a);
else
printf("%d是个合数\\n", a);
return 0;
程序主要思路:
随机出数字, 然后再定义一个变量. 先判断这个随机出的数字能不能被2,3,5整除, 如果可以, 直接输出, 然后退出程序. 如果不能, 让它为2(因为0不能作除数, 任何整数都能整除1), 然后让它一直自加, 直到和输入的数字一样.
如果自加过程中用户输入的数字能够把这个数字整除, 就结束自加(退出循环), 然后再判断自加的这个数和输入的数是否相等, 如果相等, 说明这个数之前的所有数都不能被整除, 那就是质数. 如果不相等, 说明这个数有2个以上的因数, 则是合数.
另:素数和质数是一个意思.
JAVA语言实现简单登录界面
- 程序设计思想:
使用Math.random()方法循环生成6个97~122之间的随机整数(对应ASCII码值‘a’~‘z’),将其转化为char型变量,连接成为一个6位字符串作为验证码输出,提示用户输入。用户输入字符串与验证码相符则提示通过,不相符则提示错误并再次生成随机验证码。 - 程序流程图:
- 源程序:
1 import java.awt.EventQueue; 2 import javax.swing.JFrame; 3 import java.awt.Color; 4 import javax.swing.JPanel; 5 import java.awt.BorderLayout; 6 import javax.swing.JLabel; 7 import javax.swing.JTextField; 8 import javax.swing.JPasswordField; 9 import javax.swing.JButton; 10 import javax.swing.event.*; 11 import java.awt.Font; 12 public class LoginWindow { 13 14 private JFrame frame; 15 private JPasswordField passwordField; 16 17 /** 18 * Launch the application. 19 */ 20 public static void main(String[] args) { 21 EventQueue.invokeLater(new Runnable() { 22 public void run() { 23 try { 24 LoginWindow window = new LoginWindow(); 25 window.frame.setVisible(true); 26 } catch (Exception e) { 27 e.printStackTrace(); 28 } 29 } 30 }); 31 } 32 33 /** 34 * Create the application. 35 */ 36 public LoginWindow() { 37 initialize(); 38 } 39 40 /** 41 * Initialize the contents of the frame. 42 */ 43 private void initialize() { 44 frame = new JFrame(); 45 frame.setBackground(Color.BLUE); 46 frame.setBounds(100, 100, 445, 319); 47 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 48 49 JPanel panel = new JPanel(); 50 frame.getContentPane().add(panel, BorderLayout.CENTER); 51 panel.setVisible(true); 52 panel.setLayout(null); 53 54 JLabel label = new JLabel("\\u767B\\u5F55\\u540D\\uFF1A"); //登录名标签 55 label.setFont(new Font("微软雅黑", Font.PLAIN, 18)); 56 label.setBounds(85, 44, 76, 32); 57 panel.add(label); 58 59 JLabel label_1 = new JLabel("\\u5BC6\\u7801\\uFF1A"); //密码标签 60 label_1.setFont(new Font("微软雅黑", Font.PLAIN, 18)); 61 label_1.setBounds(85, 86, 76, 32); 62 panel.add(label_1); 63 64 JLabel label_2 = new JLabel("\\u9A8C\\u8BC1\\u7801\\uFF1A"); //验证码标签 65 label_2.setFont(new Font("微软雅黑", Font.PLAIN, 18)); 66 label_2.setBounds(84, 128, 76, 30); 67 panel.add(label_2); 68 69 JTextField textArea = new JTextField(); //用户名文本框 70 textArea.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(255,0,0))); 71 textArea.setBounds(181, 44, 166, 34); 72 panel.add(textArea); 73 74 passwordField = new JPasswordField(); //密码框 75 passwordField.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(255,0,0))); 76 passwordField.setBounds(181, 86, 166, 34); 77 panel.add(passwordField); 78 79 JButton btnNewButton = new JButton("\\u767B\\u5F55"); //登录按钮 80 btnNewButton.setEnabled(false); 81 btnNewButton.setBackground(new Color(51, 153, 0)); 82 btnNewButton.setForeground(Color.BLACK); 83 btnNewButton.setBounds(124, 186, 181, 29); 84 panel.add(btnNewButton); 85 86 JButton btnNewButton_1 = new JButton("\\u5FEB\\u901F\\u6CE8\\u518C"); //快速注册按钮 87 btnNewButton_1.setBackground(new Color(255, 204, 255)); 88 btnNewButton_1.setBounds(124, 225, 181, 29); 89 panel.add(btnNewButton_1); 90 91 92 String result = ""; //验证码字符串 93 for(int i = 0;i < 6;i++) 94 { 95 int c = (int)(Math.random() * 26 + 97); //随机生成6个字符 96 result = result + (char)c; 97 } 98 JLabel lblValid = new JLabel(result); 99 lblValid.setBounds(277, 134, 70, 22); 100 panel.add(lblValid); 101 102 JTextField textArea_1 = new JTextField(); //验证码输入框 103 textArea_1.getDocument().addDocumentListener(new DocumentListener(){ //添加内容改变事件 104 public void insertUpdate(DocumentEvent e) { 105 if(textArea_1.getText().equals(lblValid.getText())){ //在文本框添加数据 106 btnNewButton.setEnabled(true); //验证码正确,登录按钮可用 107 } 108 else{ 109 btnNewButton.setEnabled(false); //验证码错误,登录按钮不可用 110 } 111 } 112 public void removeUpdate(DocumentEvent e) { //从文本框删除数据 113 if(textArea_1.getText().equals(lblValid.getText())){ 114 btnNewButton.setEnabled(true); //验证码正确,登录按钮可用 115 } 116 else{ 117 btnNewButton.setEnabled(false); //验证码错误,登录按钮不可用 118 } 119 } 120 public void changedUpdate(DocumentEvent e) { 121 122 } 123 }); 124 125 textArea_1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(255,0,0))); 126 textArea_1.setBounds(180, 128, 76, 32); 127 panel.add(textArea_1); 128 } 129 }
- 实现结果图:
- 实验总结:
- Math.random():产生一个[0,1)之间的随机数。若要产生指定范围[m,n)内随机数,可使用公式
Math.random()*(n+
1
-m) + m。本程序中为产生[97,122]之间随机整数,先使用Math.random()*(122 + 1 - 97) + 97产生一个[97,123)之间的随机数,再进通过类型转换成为整型数据(只保留整数部分)从而得到97~122之间的整数。
- 通过这次实验,我掌握了Math.random()的用法,了解了Java内类型转换的机制。另外,也初步接触了java的swing组件,熟悉了MyEclipse的设计窗口。
- 在调试过程中,我遇到的主要问题是如何给文本框添加内容改变事件,通过查找资料找到了正确的方法。相信在以后的学习中会有更深体会。
- Math.random():产生一个[0,1)之间的随机数。若要产生指定范围[m,n)内随机数,可使用公式
参考资料:
以上是关于C语言 设计并实现一种大素数随机生成方法; 实现一种快速判定任意一个大数是不是是素数方法 跪求啊的主要内容,如果未能解决你的问题,请参考以下文章