簡體   English   中英

如何在 python 中生成 8 個字節的唯一隨機數?

[英]How to generate 8 bytes unique random number in python?

有沒有辦法在 python 語言中生成一個8 字節大小的唯一隨機數? 我使用了 UUID 庫,但它有16 個字節,不符合我的要求。

任何幫助將非常感激。

提前致謝

好吧,您可以使用線性一致發電機,通過正確選擇參數,可以生成U64到U64的完美映射。 換句話說,如果您可以訪問前一個 8 字節 UUID,您可以生成合理的隨機下一個 8 字節 UUID,而無需重復,直到整個 2 64空間 ix 用完。 它還可以在 O(log(N)) 中向后和向前 N 步 go。

代碼使用 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) ) .

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM