[英]How can I generate every possible integer in a range without repeats from a seeds that is also reversible
[英]How can I make all possible list combinations using reversible seeds?
我想要一個由 100 個項目組成的列表,每個項目的值都在 0-31 之間。 然后我希望能夠獲取這些列表之一,並知道隨機生成該確切列表所需的種子/輸入。
您可以使用 Pierre L'Ecuyer 的這篇研究論文:
Tables_of_linear_congruential_generators_of_different_sizes_and_good_lattice_structure
本文給出了(相當偽隨機的) LCG示例的 2 模的最低冪是 2 30 ,接近 10 億。 見論文表 4。 只需選擇其中一個 LCG,說:
u n+1 = ((116646453 * u n ) + 5437) mod 2 30
您的每個項目正好是 5 位寬。 如果您決定將項目 6 x 6 分組,則每個組的寬度正好為 30 位,因此可以視為此模 2 30 LCG 的一種狀態。
從最初的 6 個項目組開始,LCG 的一個步驟將生成下一組,即接下來的 6 個項目。 該論文告訴您,該系列總體上看起來相當隨機。
因此,您可以將前 6 個項目視為您的“種子”,因為您可以從最左邊的 6 個項目重構整個列表。
即使假設為了混淆起見,您在種子之后開始列表的可見部分,您仍然只有大約十億個可能的種子需要擔心。 通過模擬每個可能的種子的 LCG 並與實際列表進行比較,任何體面的計算機都可以在幾秒鍾內通過蠻力找到左隱藏的種子。
可以從創建一個類開始,給定一個種子,提供 0 到 31 之間的無限系列項目:
class LEcuyer30:
def __init__ (self, seed):
self.seed = seed & ((1 << 30) - 1)
self.currGroup = self.seed
self.itemCount = 6
def __toNextGroup(self):
nextGroup = ((116646453 * self.currGroup) + 5437) % (1 << 30)
self.currGroup = nextGroup
self.itemCount = 6
def getItem(self):
if (self.itemCount <= 0):
self.__toNextGroup()
# extract 5 bits:
word = self.currGroup >> (5 * (self.itemCount - 1))
self.itemCount -= 1
return (word & 31)
我們可以創建一個包含 20 個項目的序列並打印它:
# Main program:
randomSeed = 514703103
rng = LEcuyer30(randomSeed)
itemList = []
for k in range(20):
item = rng.getItem()
itemList.append(item)
print("itemList = %s" % itemList)
itemList = [15, 10, 27, 15, 23, 31, 1, 10, 5, 15, 16, 8, 4, 16, 24, 31, 7, 5, 8, 19]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.