Random 如何手动生成随机数

Random 如何手动生成随机数,random,Random,我想手动生成随机数。我知道每种语言都有rand或random函数,但我很想知道它是如何工作的。 有人有这方面的代码吗? 介绍不同类型的随机数生成器及其创建方式。请查看以下内容: -Java中也使用了一种流行的方法 这里还有一个详细介绍了在Java的随机类中使用LCG的例子我想你指的是伪随机数。我所知道的最简单的一个(在旧机器上编写视频游戏)是这样工作的: 种子=种子*5+1 每次调用random时都会这样做,然后使用任意数量的低位*5+1有一个很好的特性(IIRC),在重复之前,不管你看了多

我想手动生成随机数。我知道每种语言都有rand或random函数,但我很想知道它是如何工作的。 有人有这方面的代码吗?


介绍不同类型的随机数生成器及其创建方式。

请查看以下内容:

-Java中也使用了一种流行的方法


这里还有一个详细介绍了在Java的随机类中使用LCG的例子

我想你指的是伪随机数。我所知道的最简单的一个(在旧机器上编写视频游戏)是这样工作的:

种子=种子*5+1

每次调用random时都会这样做,然后使用任意数量的低位*5+1有一个很好的特性(IIRC),在重复之前,不管你看了多少位,都会命中每一个可能性

当然,缺点是它的可预测性。但这在比赛中并不重要。我们疯狂地抓取各种各样的随机数,你永远不知道接下来会是什么数字


并行地做两件类似的事情,并结合结果。这是一个线性同余生成器。

POSIX.1-2001给出了
rand()
srand()
的以下实现示例,在两台不同机器上需要相同序列时可能有用

static unsigned long next = 1;
/* RAND_MAX assumed to be 32767 */
int myrand(void) {
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}
void mysrand(unsigned seed) {
    next = seed;
}
你好

手动操作的意思是“不使用计算机”还是“编写自己的代码”

如果不使用电脑,你可以使用骰子、袋子里的数字以及在电视上看到的所有选择团队、赢得宾果系列游戏等方法。拉斯维加斯充满了这些在过程(游戏)中使用的方法,旨在给你带来不好的赔率和投资回报率。您还可以获得伟大的兰德图书,并转到随机选择的页面:

(另外,为了好玩,请阅读评论)

对于编写自己的代码,您需要考虑为什么不使用RNG提供的系统还不够好。如果您使用的是现代操作系统,那么它将为用户程序提供一个RNG,这对于您的应用程序来说应该足够好了

如果你真的需要实现你自己的,有大量的生成器可用。对于非安全性使用,您可以查看LFSR链、同余生成器等。无论您需要什么分布(均匀分布、正态分布、指数分布等),您都应该能够找到带有实现的算法描述和库

对于安全使用,您应该查看Yarrow/Fortuna、NIST SP 800-89规定的PRNG和RFC 4086等信息,以获得供给PRNG所需的良好熵源。或者更好,使用操作系统中应该满足安全RNG要求的一个


RNG的实现可能是一个有趣的练习,但很少需要。不要发明你自己的算法,除非是用于玩具应用。不要,重复不要为安全应用程序发明RNG(例如生成加密密钥),至少除非您进行了一些seripus读取和调查。你会为此感谢我的(我希望)。

希望我不是多余的,因为我还没有阅读所有的链接,但我相信你可以非常接近真实的随机生成器。现在的系统往往非常复杂,即使是最优秀的极客也需要很多时间来了解系统内部发生的事情:)

只要打开你的思维,想想如果你能监控一些全局系统属性,就用它来播种。。。选择一个网络数据包(不是为你准备的?),从它的内容中计算出“某物”,并使用它来播种。。。等等。

你可以根据自己的需要设计出最适合自己的产品,并提供所有提示;)

上面显示了生成随机数的一段非常简单的代码。这是一个用C#编写的控制台程序。如果您知道任何类型的基本编程,这应该是可以理解的,并且易于转换为任何其他语言所需

DateTime只接收当前的日期和时间,大多数编程语言都有这样的功能

小时、分钟、秒和毫秒变量将日期时间值分解为其组成部分。我们只对这些部分感兴趣,所以可以忽略这一天。同样,在大多数语言中,日期和时间通常以字符串表示。在.Net中,我们有一些工具可以让我们轻松地解析这些信息。但在大多数其他以字符串形式表示时间的语言中,解析字符串中所需的部分并将其转换为数字并不太困难。这些设施通常以最古老的语言提供

种子本质上给了我们一个不断变化的起始数。传统上,你只需要将这个数字乘以0到1之间的一个十进制值,这就省去了这个步骤

上限范围定义了最大值。所以生成的数字永远不会超过这个值。而且它永远不会低于0。因此,没有任何例外。但是如果你想要否定的话,你可以手动否定它。(将其乘以-1)

实际变量randNumis包含您感兴趣的随机值

诀窍是在种子除以上限后得到余数(模数)。余数总是比除数小,在这种情况下,除数是100。简单的数学告诉你,余数不能大于除数。所以如果除以10,余数就不能大于10。在这种情况下,正是这个简单的定律使我们的随机数在0到100之间

console.writeline只将其输出到屏幕

console.readline只是暂停程序,以便您可以看到它

这是一段生成随机数的非常简单的代码。如果你每天以完全相同的间隔运行这个程序(但是你必须在相同的小时、分钟、秒和毫秒)超过一天,你将开始每隔一天一次又一次地生成相同的数字集。这是因为它是t
    static void Main()
    {
        DateTime currentTime = DateTime.Now;

        int maxValue = 100;

        int hour = currentTime.Hour;
        int minute = currentTime.Minute;
        int second = currentTime.Second;
        int milisecond = currentTime.Millisecond;

        int randNum = (((hour + 1) * (minute + 1) * (second + 1) * milisecond) % maxValue);

        Console.WriteLine(randNum);

        Console.ReadLine();
    }
struct MT{
    unsigned int *mt, k, g;
    ~MT(){ delete mt; }
    MT(unsigned int seed) : mt(new unsigned int[624]), k(0), g(0){
        for (int i=0; i<624; i++)
            mt[i]=!i?seed:(1812433253U*(mt[i-1]^(mt[i-1]>>30))+i);
    }
    unsigned int operator()(){
        unsigned int q=(mt[k]&0x80000000U)|(mt[(k+1)%624]&0x7fffffffU);
        mt[k]=mt[(k+397)%624]^(q>>1)^((q&1)?0x9908b0dfU:0);
        unsigned int y = mt[k];
        y ^= (y >> 11);
        y ^= (y << 7) & 0x9d2c5680U;
        y ^= (y << 15) & 0xefc60000U;
        y ^= (y >> 18);
        k = (k+1)%624;
        return y;
    }
};
    /// <summary>
    /// Initializes the number array from a seed provided by <paramref name="seed">seed</paramref>.
    /// </summary>
    /// <param name="seed">Unsigned integer value used to seed the number array.</param>
    private void Initialize(uint seed)
    {
        this.randBuf[0] = seed;
        for (uint i = 1; i < 100; i++)
        {
            this.randBuf[i] = (uint)(this.randBuf[i - 1] >> 1) + i;
        }
    }
    /// <summary>
    /// Refreshes the list of values in the random number array.
    /// </summary>
    private void Roll()
    {
        for (uint i = 0; i < 99; i++)
        {
            uint y = this.randBuf[i + 1] * 3794U;
            this.randBuf[i] = (((y >> 10) + this.randBuf[i]) ^ this.randBuf[(i + 399) % 100]) + i;
            if ((this.randBuf[i] % 2) == 1)
            {
                this.randBuf[i] = (this.randBuf[i + 1] << 21) ^ (this.randBuf[i + 1] * (this.randBuf[i + 1] & 30));
            }
        }
    }
    /// <summary>
    /// Retrieves a value from the random number array.
    /// </summary>
    /// <returns>A randomly generated unsigned integer</returns>
    private uint Random()
    {
        if (this.index == 0)
        {
            this.Roll();
        }

        uint y = this.randBuf[this.index];
        y = y ^ (y >> 11);
        y = y ^ ((y << 7) + 3794);
        y = y ^ ((y << 15) + 815);
        y = y ^ (y >> 18);
        this.index = (this.index + 1) % 100;
        return y;
    }
def count_in_time(n):
   import time
   count = 0
   start_time = time.clock()
   end_time = start_time + n
   while start_time < end_time:
       count += 1
       start_time += (time.clock() - start_time)
   return count


def generate_random(time_to_count, range_nums, rand_lst_size):
    randoms = []
    iterables = range(range_nums)
    count = 0
    for i in range(rand_lst_size):
        count += count_in_time(time_to_count)
        randoms.append(iterables[count%len(iterables)])
    return randoms