2 回答

TA貢獻1789條經驗 獲得超8個贊
好吧,我建議使用 LCG,Linear Congruential Generator。它有非常好的屬性——給定正確的常量集(赫爾-多貝爾定理)輸出唯一地覆蓋所有 2 32空間(或 64 位空間,但據我記得 PHP 只有 32 位整數)?;旧纤菑?[0...2 32 ) 間隔到另一個 [0...2 32 ) 間隔的一對一映射器。它可以以兩種方式使用
一、ID next = LCG(ID prev ),就像典型的隨機數生成器一樣?;蛘咧皇菑木€性遞增計數器 ID next = LCG(1, 2, ...) 中輸入它。您可以將整數轉換為 8 個符號 base-16 字符串,應該足夠好了。
沒有 PHP 代碼,有一個 python 代碼
import numpy as np
class LCG:
UZERO: np.uint32 = np.uint32(0)
UONE : np.uint32 = np.uint32(1)
def __init__(self, seed: np.uint32, a: np.uint32, c: np.uint32) -> None:
self._seed: np.uint32 = np.uint32(seed)
self._a : np.uint32 = np.uint32(a)
self._c : np.uint32 = np.uint32(c)
def next(self) -> np.uint32:
self._seed = self._a * self._seed + self._c
return self._seed
def seed(self) -> np.uint32:
return self._seed
def set_seed(self, seed: np.uint32) -> np.uint32:
self._seed = seed
def skip(self, ns: np.int32) -> 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.uint32 = np.uint32(ns)
a: np.uint32 = self._a
c: np.uint32 = self._c
a_next: np.uint32 = LCG.UONE
c_next: np.uint32 = 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.uint32(1664525)
c = np.uint32(1013904223)
seed = np.uint32(1)
rng = LCG(seed, a, c)
print(rng.next())
print(rng.next())
print(rng.next())

TA貢獻1770條經驗 獲得超3個贊
我寫的一篇文章包含有關唯一隨機標識符的建議。從您的問題來看,您似乎面臨以下困境:生成隨機唯一標識符——
足夠長以至于難以猜測,但是
足夠短,便于最終用戶輸入。
那篇文章中的建議解釋了如何生成唯一的隨機 ID(128 位或更長,使用加密 RNG,例如random_bytes
在bin2hex
PHP 中)。但出于您的目的,生成的 ID 可能太長而不適合。有一些方法可以處理如此長的 ID,包括——
將 ID 劃分為可記憶的塊(例如:“374528294473”變為“374-538-294-473”),
將 ID 轉換為一系列容易記住的單詞(如比特幣的 BIP39),或
在 ID 的末尾添加一個所謂的“校驗和數字”以防止輸入錯誤。
在決定使用比該文章中的建議更短的 ID 之前,您應該嘗試 (1) 或 (2)。
此外,您的應用程序通常必須根據已生成的 ID 數據庫檢查 ID 的唯一性;但是,這種唯一性檢查可能會或可能不會成為您的應用程序的性能瓶頸,唯一的方法是嘗試并查看?;蛘?,您可以將 ID 表的記錄號(對于每條記錄應該是唯一的)包含在 ID 本身中。
如果訂單 ID 是唯一授予訪問該訂單信息的權限,則也可能存在嚴重的安全問題。理想情況下,應該有其他形式的授權,例如只允許登錄用戶或某些登錄用戶訪問與訂單 ID 關聯的訂單信息。另請參閱此問題。
- 2 回答
- 0 關注
- 162 瀏覽
添加回答
舉報