簡體   English   中英

如何使用可逆種子制作所有可能的列表組合?

[英]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 並與實際列表進行比較,任何體面的計算機都可以在幾秒鍾內通過蠻力找到左隱藏的種子。

示例 Python 代碼:

可以從創建一個類開始,給定一個種子,提供 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.

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