在C#中生成2个随机素数 [英] Generating 2 random prime number in C#

查看:96
本文介绍了在C#中生成2个随机素数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想问一下,我如何生成2个随机数,然后检查它是否是素数?我想生成两个并一键检查它们。我试图在C#中编写代码但是有一些无效的参数。这是我的代码。





  protected   void  btnstart_Click( object  sender,EventArgs e)
{
BigInteger p = RandomInteger(); // 生成随机数
(CheckIfPrime(p)== false // 生成的数字将检查是否为素数,如果为假,则重新生成另一个随机数
{
BigInteger p = RandomInteger();
}
txtP.Text = p.ToString(); // 输出素数
lblresult.Text = true; // 结果为true以确认它是素数


BigInteger q = RandomInteger();
txtQ.Text = q.ToString();
lblresult2.Text = true;
}

public BigInteger RandomInteger() // 生成一个随机数
{
var rng = new RNGCryptoServiceProvider();
var n = 10000000000 ;
byte [] bytes = new byte < /跨度> [N / 8];

rng.GetBytes(bytes);

var msb = bytes [n / 8 - 1 ];
var mask = 0 ;
while (mask < msb)
mask =(mask<< ; 1 )+ 1 ;

bytes [n - 1 ]& = Convert.ToByte(mask);
BigInteger i = new BigInteger(字节);
return i;
}

public bool CheckIfPrime( int n) // 检查生成的随机数是否为素数
{
var isPrime = true ;
var sqrt = Math.Sqrt(n);
for var i = 2 ; i < = sqrt; i ++)
if ((n%i) == 0 )isPrime = false ;
return isPrime;
}







谢谢!

解决方案

我会反过来说,就是直接随机生成一个素数。你知道,在 10,000,000,000 下,有 455,052,511 素数(见有多少素数? [ ^ ])所以你可以在 0 之间随机选择 r 455,052,510 然后使用 r th 素数。可能预先计算好的素数(巨大!)表会有所帮助。


你的代码中的问题是你调用'CheckIfPrime传递它'BigInteger,但它的参数是:'int 。



还有一个问题是数学库'Sqrt函数不接受Type'BigInteger。你可以解决这个问题:



< br /> 
BigInteger sqrt = Math.Exp(BigInteger.Log( bigIntValue)/ 2);

//参见:[ ^ ]。



想想您想要随机选择的素数值的范围;你使用'BigInteger意味着......嗯......非常大。如你所知,确定非常大数字的素数可能需要大量的计算能力。



有公开的素数列表,包括非常大的素数;你可以使用你随机选择的列表来实现你的解决方案吗?这里有5000个非常大的素数列表(每个最少1000个数字):[ ^ ]。



重新获得两个随机值同时:如果你有多核可以使用,请考虑使用并行编程.NET:[ ^ ]。



这使用'System.Security.Cryptography RNGCrytoServiceProvider工具来获取具有一定位数的随机大整数:

  //  请注意,此代码来自名为NameSpace中的方法的名为PrimeUtilties  
$ b $的静态类b private static RNGCryptoServiceProvider rngProvider = new RNGCryptoServiceProvider ();
private static 随机随机= new Random(DateTime.Now.Millisecond);
private static byte [ ] someBytes;

public static BigInteger GetRandomBigInteger( int nBits, bool onlyPositive = true
{
someBytes = new byte [nBits / 8];
rngProvider.GetBytes(someBytes);

BigInteger bg = new BigInteger(someBytes);
if (onlyPositive&& bg.Sign == -1)bg = bg * -1;

return bg;
}

您可以使用元组从方法中返回两个值:

  public   static 元组< BigInteger,BigInteger> GetTwoRandomBigInts( int  nbitsOf1 =  128  int  nbitsOf2 =  128  bool  onlyPositive =  true 
{
return Tuple.Create(GetRandomBigInteger(nbitsOf1,onlyPositive),GetRandomBigInteger(nbitsOf2,onlyPositive));
}

// 获取一个包含两个(非负)BigInts的元组
// var TwoBigOnesWith = PrimeUtilities.Methods.GetTwoRandomBigInts(512,256,onlyPositive:true );

但是,通常我不打算像这样编写硬编码的方法;我写了一个更普遍的一个,它采用了一个'param数组,或者传递了一些我要解析的结构来生成我想要创建的BigIntegers的一堆,或者一堆串。


你的代码有很多问题。

其中一个是效率,这是你的代码和两个微不足道的变化:

  public   bool  CheckIfPrime( int  n)  //  检查生成的随机数是否为素数 
{
var isPrime = true ;
var sqrt = Math.Sqrt(n);
for var i = 2 ; i < = sqrt; i ++)
if ((n%i) == 0 )isPrime = false ;
return isPrime;
}

对于n = 400,代码检查2,3,4,5,6,7,8,9,10,11,12,13,14,15 ,16,17,18,19,20



  public  < span class =code-keyword> bool  CheckIfPrime( int  n) //  < span class =code-comment>检查生成的随机数是否为素数 
{
var isPrime = ;
var sqrt = Math.Sqrt(n);
if ((n% 2 )== 0 )isPrime = false ;
for var i = 3 ; i < = sqrt; i + = 2
if ((n%i)== 0 )isPrime = false ;
return isPrime;
}

对于n = 400,代码检查2,3,5,7,9,11,13,15,17,19



  public   bool  CheckIfPrime( int  n) //  检查生成的随机数是否为素数 
{
var sqrt = Math.Sqrt(n);
if ((n% 2 )== 0 return false ;
for var i = 3 ; i < = sqrt; i + = 2
if ((n%i)== 0 return < span class =code-keyword> false ;
return true ;
}

这里代码在知道 n 不是素数时就会停止。



已经发现, int n 该函数的参数是错误的,因为你要查看 BigInteger


Would like to ask, how do I generate 2 random numbers and then check if it is a prime? I would like to generate both and check them all in one click. I tried to write the code in C# but there are some invalid arguments. Here is my code.


protected void btnstart_Click(object sender, EventArgs e)
        {
            BigInteger p = RandomInteger(); //generate a random number
            while (CheckIfPrime(p)==false) // number generated will be check if is prime,if false regenerate another random number
            {
                BigInteger p = RandomInteger();
            }
            txtP.Text = p.ToString(); // output the prime number
            lblresult.Text = "true"; // result true to confirm that it is the prime


            BigInteger q = RandomInteger();
            txtQ.Text = q.ToString();
            lblresult2.Text = "true"; 
        }

        public BigInteger RandomInteger() // to generate a random number
        {
            var rng = new RNGCryptoServiceProvider();
            var n = 10000000000;
            byte[] bytes = new byte[n/8];

            rng.GetBytes(bytes);

            var msb = bytes[n / 8 - 1];
            var mask = 0;
            while (mask < msb)
                mask = (mask << 1) + 1;

            bytes[n - 1] &= Convert.ToByte(mask);
            BigInteger i = new BigInteger(bytes);
            return i;
        }
        
        public bool CheckIfPrime(int n) //to check if the random number generated is prime
        {
            var isPrime = true;
            var sqrt = Math.Sqrt(n);
            for (var i = 2; i <= sqrt; i++)
                if ((n % i) == 0) isPrime = false;
            return isPrime;
        }




Thank you!

解决方案

I would do the opposite, that is directly random generate a prime number. You know, under 10,000,000,000 there are 455,052,511 prime numbers (see How many primes are there?[^]) so you can randomlly choose r between 0 and 455,052,510 and then use the rth prime number. Possibly a pre-computed prime numbers (huge!) table would help.


The problem in your code is that you call 'CheckIfPrime passing it a 'BigInteger, but its parameter is: 'int.

There's also a problem in that the Math library 'Sqrt Function will not accept Type 'BigInteger. You can work around that with this:

<br />
BigInteger sqrt = Math.Exp(BigInteger.Log(bigIntValue) / 2); 

// see: [^].

Think about the range of values you want the randomly selected primes within; your use of 'BigInteger implies ... well ... very large. As you know, determining the "primality" of very large numbers can take massive amounts of computation power.

There are publicly available lists of primes, including very large primes; could you implement your solution using a list from which you randomly select ? There's a list of 5000 very large primes here (minimum 1000 digits each): [^].

Re the issue of getting two random values "simultaneously:" if you have multi-cores to work with, consider using parallel programming in .NET: [^].

This uses 'System.Security.Cryptography the RNGCrytoServiceProvider facility to get random big integers with a certain number of bits:

// note this code is from a a static Class named 'Methods in a NameSpace named 'PrimeUtilties

private static RNGCryptoServiceProvider rngProvider = new RNGCryptoServiceProvider();
private static Random random = new Random(DateTime.Now.Millisecond);
private static byte[] someBytes;

public static BigInteger GetRandomBigInteger(int nBits, bool onlyPositive = true)
{
    someBytes = new byte[nBits/8];
    rngProvider.GetBytes(someBytes);
    
    BigInteger bg = new BigInteger(someBytes);
    if (onlyPositive && bg.Sign == -1) bg = bg * -1;
    
    return bg;
}

You can use a Tuple to return two values from a Method:

public static Tuple<BigInteger, BigInteger> GetTwoRandomBigInts(int nbitsOf1 = 128, int nbitsOf2 = 128, bool onlyPositive = true)
{
    return Tuple.Create(GetRandomBigInteger(nbitsOf1, onlyPositive), GetRandomBigInteger(nbitsOf2, onlyPositive));
}

// get a Tuple with two (non-negative) BigInts
// var TwoBigOnesWith = PrimeUtilities.Methods.GetTwoRandomBigInts(512, 256, onlyPositive: true);

But, normally I wouldn't bother writing a hard-coded method like that; I'd write a more general one that took a 'param array, or passed in some structure that I'd parse to generate whatever bunch, or, bunch-of-bunches, of BigIntegers I wanted to create.


Your code have numerous problems.
One of them is efficiency, here is your code and 2 trivial changes:

public bool CheckIfPrime(int n) //to check if the random number generated is prime
{
    var isPrime = true;
    var sqrt = Math.Sqrt(n);
    for (var i = 2; i <= sqrt; i++)
        if ((n % i) == 0) isPrime = false;
    return isPrime;
}

for n=400 the code checks 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20

public bool CheckIfPrime(int n) //to check if the random number generated is prime
{
    var isPrime = true;
    var sqrt = Math.Sqrt(n);
    if ((n % 2) == 0) isPrime = false;
    for (var i = 3; i <= sqrt; i+= 2)
        if ((n % i) == 0) isPrime = false;
    return isPrime;
}

for n=400 the code checks 2, 3, 5, 7, 9, 11, 13, 15, 17, 19

public bool CheckIfPrime(int n) //to check if the random number generated is prime
{
    var sqrt = Math.Sqrt(n);
    if ((n % 2) == 0) return false;
    for (var i = 3; i <= sqrt; i+= 2)
        if ((n % i) == 0) return false;
    return true;
}

and here the code stops as soon as it knows n is not a prime.

As already spotted, int n parameter of the function is wrong since you want to check a BigInteger.


这篇关于在C#中生成2个随机素数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆