随机数生成器

分类:生成工具
在线随机数生成器,可以按照您设定的规则,随机生成一组数字,这些数字可以是唯一的,也可以是重复的。生成的结果可以应用于抽奖、测试数据或者其他需要随机数字的应用中。本工具使用梅森旋转算法来生成伪随机数。
本次要生成的随机数的个数,最多不超过1000个
生成的随机数的最小值,该值不能小于0
生成的随机数的最大值,必须大于上面的「最小值」

工具介绍

随机数生成器,可以根据指定的规则,随机生成一组数字。

本工具使用梅森旋转算法(Mersenne Twister)来模拟随机行为,因为真实的随机数是通过物理现象产生的,比如:抛掷钱币、摇骰子、电子元件的噪音、核裂变等等。这样的随机数发生器叫做物理性随机数发生器,本工具是通过一定的算法来达到产生随机数的效果,在计算机领域称为「伪随机」。伪随机数具有随机数的统计特征,因此,在大部分应用场景中,伪随机数即可满足要求。

选项说明

随机数生成器提供了几个选项来生成需要的随机数:

  • 生成个数:指定本次生成多少个随机数
  • 最小值:指定生成的随机数的最小值(含),必须大于等于0
  • 最大值:指定生成的随机数的最大值(含),必须大于最小值
  • 生成结果:这里指定生成的结果是否要求唯一或允许重复

点击「生成随机数」按钮,即可按照设定的规则,生成一组随机数。

生成的随机数可应用于抽奖、测试 Mock 数据或者其他需要随机数字的应用中。

附:梅森旋转算法简介

梅森旋转算法(Mersenne twister)是一个伪随机数发生算法。由松本真和西村拓士在 1997 年开发,基于有限二进制字段上的矩阵线性递归,对于一个 k 位 2 进制数,梅森旋转算法可在 [0, 2^k-1] 的范围内生成离散型均匀分布的随机数。该算法可以快速产生高质量的伪随机数,修正了古典随机数发生算法的很多缺陷。

优点

  • 许可免费,而且对所有它的变体专利免费(除 CryptMT 外);
  • 在应用最广泛的 MT19937 变体中,周期非常长,达到 2^19937-1
  • 1 ≤ k ≤ 623 的维度之间都可以均等分布;
  • 除了在统计学意义上的不正确的随机数生成器以外,比其他伪随机数生成算法要快;

缺点

  • 需要大量的缓冲器(2.5kib),但在 TinyMT 版本中得到修正(只需 127 bits)
  • 吞吐量中等,但在 SFMT 版本中修正
  • 产生的随机数与 seed 相关,不能用于蒙特卡洛模拟
  • 由相同的初始序列产生的随机状态几乎相同
  • 非加密安全的,除 CryptMT 外

算法过程

整个算法主要分为三个阶段:

  • 第一阶段:获得基础的梅森旋转链;
  • 第二阶段:对于旋转链进行旋转算法;
  • 第三阶段:对于旋转算法所得的结果进行处理;

算法实现的过程中,参数的选取取决于梅森素数,故此得名。

梅森旋转算法的 C 语言实现

下面是梅森旋转算法的 C 语言实现代码,供参考:

#include <stdint.h>

// 定义MT19937-32的常数
enum
{
    // 假定 W = 32 (此项省略)
    N = 624,
    M = 397,
    R = 31,
    A = 0x9908B0DF,

    F = 1812433253,

    U = 11,
    // 假定 D = 0xFFFFFFFF (此项省略)

    S = 7,
    B = 0x9D2C5680,

    T = 15,
    C = 0xEFC60000,

    L = 18,

    MASK_LOWER = (1ull << R) - 1,
    MASK_UPPER = (1ull << R)
};

static uint32_t  mt[N];
static uint16_t  index;

// 根据给定的seed初始化旋转链
void Initialize(const uint32_t  seed)
{
    uint32_t  i;
    mt[0] = seed;
    for ( i = 1; i < N; i++ )
    {
        mt[i] = (F * (mt[i - 1] ^ (mt[i - 1] >> 30)) + i);
    }
    index = N;
}

static void Twist()
{
    uint32_t  i, x, xA;
    for ( i = 0; i < N; i++ )
    {
        x = (mt[i] & MASK_UPPER) + (mt[(i + 1) % N] & MASK_LOWER);
        xA = x >> 1;
        if ( x & 0x1 )
        {
            xA ^= A;
        }
        mt[i] = mt[(i + M) % N] ^ xA;
    }

    index = 0;
}

// 产生一个32位随机数
uint32_t ExtractU32()
{
    uint32_t  y;
    int       i = index;
    if ( index >= N )
    {
        Twist();
        i = index;
    }
    y = mt[i];
    index = i + 1;
    y ^= (y >> U);
    y ^= (y << S) & B;
    y ^= (y << T) & C;
    y ^= (y >> L);
    return y;
}