如何在python中生成8字节的唯一随机数?

2024-04-19 18:05:24 发布

您现在位置:Python中文网/ 问答频道 /正文

在python语言中,是否有任何方法可以生成大小为8字节的唯一随机数?我使用了UUID库,但它有16个字节,这与我的要求不一致

任何帮助都将不胜感激

提前谢谢


Tags: 方法语言字节uuid
2条回答

好的,您可以使用Linear Congruential Generator,通过适当的参数选择,它可以生成从u64到u64的完美映射。换句话说,如果您可以访问之前的8字节UUID,则可以生成合理的随机下一个8字节UUID,而无需重复,直到整个264space ix耗尽。它还可以在O(log(N))中前后移动N步

代码使用NumPy、Python 3.7、Anaconda、Win 10 x64

#%%
import numpy as np

#%%
class LCG(object):

    UZERO: np.uint64 = np.uint64(0)
    UONE : np.uint64 = np.uint64(1)

    def __init__(self, seed: np.uint64, a: np.uint64, c: np.uint64) -> None:
        self._seed: np.uint64 = np.uint64(seed)
        self._a   : np.uint64 = np.uint64(a)
        self._c   : np.uint64 = np.uint64(c)

    def next(self) -> np.uint64:
        self._seed = self._a * self._seed + self._c
        return self._seed

    def seed(self) -> np.uint64:
        return self._seed

    def set_seed(self, seed: np.uint64) -> np.uint64:
        self._seed = seed

    def skip(self, ns: np.int64) -> None:
        """
        Signed argument - skip forward as well as backward

        The algorithm here to determine the parameters used to skip ahead is
        described in the paper F. Brown, "Random Number Generation with Arbitrary Stride,"
        Trans. Am. Nucl. Soc. (Nov. 1994). This algorithm is able to skip ahead in
        O(log2(N)) operations instead of O(N). It computes parameters
        A and C which can then be used to find x_N = A*x_0 + C mod 2^M.
        """

        nskip: np.uint64 = np.uint64(ns)

        a: np.uint64 = self._a
        c: np.uint64 = self._c

        a_next: np.uint64 = LCG.UONE
        c_next: np.uint64 = LCG.UZERO

        while nskip > LCG.UZERO:
            if (nskip & LCG.UONE) != LCG.UZERO:
                a_next = a_next * a
                c_next = c_next * a + c

            c = (a + LCG.UONE) * c
            a = a * a

            nskip = nskip >> LCG.UONE

        self._seed = a_next * self._seed + c_next


#%%
np.seterr(over='ignore')

a = np.uint64(6364136223846793005)
c = np.uint64(1)

seed = np.uint64(1)

rng64 = LCG(seed, a, c)

print(rng64.next())
print(rng64.next())
print(rng64.next())

#%%
rng64.skip(-3) # back by 3
print(rng64.next())
print(rng64.next())
print(rng64.next())

rng64.skip(-3) # back by 3
rng64.skip(2) # forward by 2
print(rng64.next())

在Python 3.6及更高版本中,这很容易:

  • 导入secrets模块:import secrets
  • secrets.token_bytes(8)生成一个随机字节序列。或者,如果字符串应该是可读的,则使用以下命令,从8个字节中生成16个字符的字符串(secrets.token_hex(8)),或从4个字节中生成8个字符的字符串(secrets.token_hex(4)

相关问题 更多 >