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;

调试编译好了,没问题了


截图:

大一点的数运行起来有点慢哦!

参考技术A

    目前来说大素数随机生成方法是不存在的,这是一个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两个解。


参考技术B int main(void)

    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语言实现简单登录界面

  1. 程序设计思想:
      使用Math.random()方法循环生成6个97~122之间的随机整数(对应ASCII码值‘a’~‘z’),将其转化为char型变量,连接成为一个6位字符串作为验证码输出,提示用户输入。用户输入字符串与验证码相符则提示通过,不相符则提示错误并再次生成随机验证码。
  2. 程序流程图:
  3. 源程序:
      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 }
  4. 实现结果图:
  5. 实验总结:
    • 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的设计窗口。
    • 在调试过程中,我遇到的主要问题是如何给文本框添加内容改变事件,通过查找资料找到了正确的方法。相信在以后的学习中会有更深体会。

    参考资料:

    http://www.yiibai.com/swing/home.html

    https://zhidao.baidu.com/question/554112250.html

以上是关于C语言 设计并实现一种大素数随机生成方法; 实现一种快速判定任意一个大数是不是是素数方法 跪求啊的主要内容,如果未能解决你的问题,请参考以下文章

C语言中判断N个数中的素数并求和

在C语言中怎样产生随机的字符串

c语言怎么判断一个数是素数

产生一个随机数(伪随机)的一种方法(c语言)

c语言:实现对于给定的正整数N,依次打印出小于等于N的所有素数。两种方法及其优化

c语言:实现对于给定的正整数N,依次打印出小于等于N的所有素数。两种方法及其优化