我们需要在伪随机数生成器中实现Blum Blum Shub算法。我尝试在c#中搜索实现以了解想法,但未成功。我们需要实现的一些方法不够清晰(或者也许我没有确切地得到他们的要求)。
任何人都可以以类似的方式提供有关代码或示例的帮助吗?我很难理解文本中的概念。任何帮助都会被接受!
首先,我尝试遵循问题的逻辑。由于进展甚微,我开始在网上搜索更好的解释,并可能找到实现更好的理解的实现。最后,我尝试用我认为合理的方法填充一些请求的方法。
static long seed = 6367859;
static long p = 3263849;
static long q = 1302498943;
static long m = p*q;
// Generates a random bit i.e. 0 or 1 using the Blum Blum Shub Algorithm and the Least Significant Bit
private byte generateRandomBit(){ }
// Method to generate a single positive 32 bit random number using the Blum Blum Shub Algorithm.
// The generateRandomBit() method is used to generate the random bits that make up the random number
// Not complete!!
public int GenerateNextRandomNumber()
{
int nextRandomNumber = (int)((p * seed + q) % m);
seed = nextRandomNumber;
return nextRandomNumber;
}
// Generates a random number between min and max.
// The GenerateNextRandomNumber() method must be used to generate the initial random number which must then be manipulated (if necessary) to be between min and max
public int GenerateNextRandomNumber(int min, int max){ }
// Uses the GenerateNextRandomNumber Method to generate a sequence of Random Numbers between the minimum and the maximum value using the Blum Blum Shub Algorithm
public int[] GenerateRadmonSequence(int n, int min, int max)
{
int[] sequence = new int[n];
for (int i = 0; i < n; i++)
{
int randNum = Math.Abs(GenerateNextRandomNumber());
randNum = min + randNum % (max + 1 +- min);
sequence[i] = randNum;
}
return sequence;
}
结果应该是生成一个从最小到最大的数字序列。
答案 0 :(得分:0)
否,此类RNG不能使用long,这几乎需要任意精度数学。实际上,您实现的是Linear Congruential Generator,而不是Blum Blum Shub算法。
.NET Core 2.2,x64 Win10是帮助您入门的代码。使用BigInteger,我认为合适的算法和奇偶校验来获取下一个随机位。您也可以将最低有效位用于随机位。
using System;
using System.Numerics;
namespace BlumBlumSnub
{
class Program
{
public static readonly BigInteger p = 3263849;
public static readonly BigInteger q = 1302498943;
public static readonly BigInteger m = p*q;
public static BigInteger next(BigInteger prev) {
return (prev*prev) % m;
}
public static int parity(BigInteger n) {
BigInteger q = n;
BigInteger count = 0;
while (q != BigInteger.Zero) {
count += q & BigInteger.One;
q >>= 1;
}
return ((count & BigInteger.One) != BigInteger.Zero) ? 1 : 0; // even parity
}
public static int LSB(BigInteger n) {
return ((n & BigInteger.One) != BigInteger.Zero) ? 1 : 0;
}
static void Main(string[] args)
{
BigInteger seed = 6367859;
BigInteger xprev = seed;
for(int k = 0; k != 100; ++k) {
BigInteger xnext = next(xprev);
int bit = parity(xnext); // extract random bit from generated BBS number using parity,
// or just int bit = LSB(xnext);
Console.WriteLine($"Bit = {bit}");
xprev = xnext;
}
}
}
}
答案 1 :(得分:0)
该实现如何?
public class BlumBlumShub
{
private readonly ulong m;
private ulong x;
public BlumBlumShub(int m, int seed)
{
this.m = (ulong) m;
x = (ulong)seed;
}
public int Next()
{
x = (x * x) % m;
return (int)x;
}
}
编辑::如果您确实需要非常多的数字,可以轻松进行调整:
public class BlumBlumShub
{
private readonly BigInteger m;
private BigInteger x;
public BlumBlumShub(BigInteger m, BigInteger seed)
{
this.m = m;
x = seed;
}
public BigInteger Next()
{
x = (x * x) % m;
return x;
}
}