📜  随机 bigint javascript (1)

📅  最后修改于: 2023-12-03 15:12:49.103000             🧑  作者: Mango

随机 BigInt JavaScript

在 JavaScript 中, Math.random() 方法允许我们生成一个0到1之间的随机数。但是,如果你需要生成一个随机的大整数,JavaScript 并不提供直接的方法。因此, 我们需要使用一些库或者自己实现一个方法来生成一个随机的 BigInt 值。

在本文中,我们将讨论一些方法以及使用这些方法来生成一个随机的 BigInt 值。

几种生成随机 BigInt 的方法
生成双精度浮点数

我们可以通过生成一个零到一个很大浮点数的方法得到一个 BigInt。具体步骤如下:

  1. 生成一个 0 到 $2^{53} - 1$ 之间的随机数。因为浮点数的最大值是 $2^{53}$,所以我们需要减去 1。
  2. 使用 Math.round() 方法来取整数。
  3. 将该整数转换成 BigInt。

这种方法的缺点是 $2^{53} - 1$ 并不是一个 BigInt。因此,我们必须将其转换成 BigInt 类型。以下是实现代码:

function randomBigIntGenerator() {
  const maximumSafeInteger = BigInt(Number.MAX_SAFE_INTEGER);
  const randomNumber = Math.floor(Math.random() * maximumSafeInteger);
  return BigInt(randomNumber);
}
生成字符串

我们可以使用任意长度的字符串来生成一个随机的 BigInt。以下是具体步骤:

  1. 生成一个指定长度的随机字符串。
  2. 将字符串转换为 BigInt。

在这种情况下,我们需要一个生成随机字符串的方法。以下是一个使用 Math.random() 方法和字符串的 slice() 方法来生成指定长度的随机字符串的实现代码:

function randomStringGenerator(length) {
  let result = '';
  const randomChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  for (let i = 0; i < length; i++) {
    result += randomChars.charAt(Math.floor(Math.random() * randomChars.length));
  }
  return result;
}

function randomBigIntGenerator(length) {
  const randomString = randomStringGenerator(length);
  return BigInt(randomString);
}
扩展 Miller-Rabin 算法

Miller-Rabin 算法是一种常用的素数测试算法,它也可用于生成随机 BigInt。以下是具体步骤:

  1. 随机一个范围在 $2^{n-1}$ 到 $2^n - 1$ 之间的素数。
  2. 将该素数转换为 BigInt。

但是,如果需要生成大位数的数值,这种方法会相当消耗时间和计算资源。因此, 我们还需要使用一些优化,例如二分搜索、多线程实现等等。以下是一个简单的实现:

function isProbablePrime(n, k = 5) {
  if (n === 2 || n === 3) { return true; }
  if (n === 1 || n % 2 === 0) { return false; }

  const s = n - 1;
  let d = s;
  while (d % 2 === 0) {
    d /= 2;
  }
  
  WitnessLoop:
  for (let i = 0; i < k; ++i) {
    const a = Math.floor(Math.random() * (n - 2)) + 2;
    let x = BigInt(Math.pow(a, d)) % n;

    if (x === 1 || x === s) {
      continue;
    }

    for (let r = 1; r < s; ++r) {
      x = (BigInt(x) * BigInt(x)) % n;
      if (x === s) {
        continue WitnessLoop;
      }
      if (x === 1) {
        return false;
      }
    }
    return false;
  }
  return true;
}

function randomBigIntGenerator(length) {
  const minimumNumber = BigInt(Math.pow(2, length - 1));
  const maximumNumber = BigInt(Math.pow(2, length)) - BigInt(1);

  let randomBigInt = BigInt(4);
  while (!isProbablePrime(randomBigInt)) {
    randomBigInt = BigInt(bigIntRandBetween(minimumNumber, maximumNumber));
  }
  return randomBigInt;
}

该函数的运行时间与生成的数值位数相关,一般情况下,生成一个相对较小的 BigInt 需要的时间会更少。

结论

在本文中,我们介绍了三种方法来生成随机 BigInt。这些方法未必是最好的,但对于需要一个随机 BigInt 的程序很有用。其中,Miller-Rabin 算法需要的时间与生成的 BigInt 长度相关, 因此,需要在一些应用场景中使用。

祝你好运!