計算生成特定虛榮地址難度的最佳方法?
我現在正在使用小型工具,其目的是計算獲取虛榮地址的難度(如嘗試次數),就像 vanitygen (<https://github.com/samr7/vanitygen>)一樣。我已經閱讀了一些材料(<https://en.bitcoin.it/wiki/Vanitygen#Difficulty_of_finding_a_vanity>),現在我想知道必須如何進行這種計算的確切算法。在 bitcoin.it wiki 的文章中沒有確切的答案,所以查看 vanitygen 的來源並最終得到一些非常基本的想法:
- 簡而言之,所有地址都是 base58 數字,如果需要,可以轉換為大整數。
- 有一個最終的“最大”地址(例如某個範圍末尾的最大數字)
- 虛地址是地址範圍內的任何地址(如果我們將它們視為數字),以特定模式開頭。
那麼找到指定虛地址的難度的最佳方法是什麼?我最終有了這樣的想法:
- 找到可能的最大地址並將其轉換為 bigint。
- 查找給定虛榮圖案的地址範圍。首先,通過將 z 添加到模式的末尾,同時它小於最大可能地址,找到範圍內可能的最大地址。然後為了獲得範圍內的最小地址,我決定將 1(0 的 base58 表示)添加到虛榮模式中,但我無法確定何時必須停止。顯然地址不能超過 34 個符號,但我什麼時候必須停下來?我認為我必須取該範圍內最大地址的長度,而最小地址的長度相同。但是,如果我錯了,請糾正我。
- 當我們有地址範圍時,我們可以通過從最大的地址中減去最小的地址來計算它的長度,然後將可能的最大地址除以範圍長度,結果就是我們的難度。
那麼這一切都正確嗎?當模式以“1”開頭時我該怎麼辦?
您可以建議閱讀哪些其他材料?
所以事情變得有點不同了。但是現在我有一個解決方案,這似乎可行且足夠。最初的任務是計算找到特定虛榮地址的難度(就像 vanitygen 所做的那樣)。
難點基本上是 number_of_all_possible_addresses / number_of_addresses_with_vanity_prefix率。
因此,例如,如果我們只有 0 到 9999 之間的 dec 地址,則很難找到虛地址,以“1”開頭的將是 10,因為 10000 是所有可能地址的數量,並且只有 1000..1999 中的地址才會匹配,所以有 1000 個。
使用比特幣地址,事情會稍微複雜一些,但原理是一樣的。
首先讓我們看看比特幣地址是如何形成的:簡而言之,有幾個步驟對我們的任務很重要:
- 取一個 0x00 字節(這將是地址的第一個字節來表示它的版本)
- 獲取ripemd160 結果(20 字節,160 位)。
- 取 sha256(sha256(ripemd160)) 的前四個字節作為校驗和
- 連接 0x00+ 20 字節的成熟 + 4 字節的 sha256 的 sha256 的成熟
- 現在你得到一個 25 字節長的東西,你必須把它當作一個長整數。我們將此號碼稱為“原始地址”。
- Base58檢查它(但現在這不是很重要),結果將是比特幣地址。
但是,重要的是要了解一個事實,即我們只能更改ripemd 部分。這導致我們得出兩個結論:首先是只有 2^160 個比特幣地址,其次是有點複雜。
讓我們找到一個重要問題的答案:如果 A 和 B 是以相同數字開頭的數字,並且有一個 X,例如 A < X < B,這是否意味著 X 以相同數字開頭?如果 A 是 1000 而 B 是 1999 - 是的。X 可以是 1001 到 1998 之間的任何數字。但是如果 A 是 100 而 B 是 10000 會怎樣?X 可以是它們之間的任何數字,並且不能以相同的數字開頭。因此,只有當 A、X 和 B 的位數相同時,它們的開頭必須具有相同的數字。記住,這很重要。
讓我們弄清楚,什麼是虛地址,什麼是base58編碼。
Base58 類似於 base16 和 base2 和 base10 以及其他所有基礎。例如,符號“A”在 base58 中是“A”,在 base16 中是 0x09,在 base10 中是 9。這是一個很好的起點。
讓我們決定我們的地址以“1A”開頭。我們知道地址基本上是一個 25 字節的整數。什麼是“1A”?它是base58 中的“1A”和base10 中的0009。或者只有 9 個。
這意味著每個可以除以 58 並且商等於“9”的數字將在 base58 期間給我們一個“A”符號。例如 522/58 == 9. 30276/58/58 == 9. 但不僅這些數字會以 9 結尾,這些數字也會:
- 9*58 + 58 -1
- 9*58^2 + 58^2 - 1
- 9*58^3 + 58^3 -1
- 或任何 (9 + 1)*58^N -1 數字
所以公式是范圍的開始:
前綴*58^n
對於範圍的結尾:
(前綴 + 1)*58^n -1
這裡有一個想法:我們必須找到滿足這些要求的所有數字範圍:
- 範圍開頭的數字和範圍結尾的數字具有相同的位數
- 這些數字的長度必須等於 proto-address 的長度。這很重要,因為我們必須有一個以 0 字節開頭的 25 字節長的整數,這是規律!
- 它們的值必須小於 2^192,因為前導字節始終為 00,而我們只有 25 個字節,這使我們只有 24 個字節或 192 位可以更改值。
當我們找到所有這些範圍時,我們可以通過簡單地從範圍的結尾減去範圍的開頭來找到該範圍中有多少個數字。我們範圍的所有長度的總和將是我們可以獲得多少可能的原始地址。
但這不是結束。我們記得,原始地址只是所有可能的大數字,因此並非所有這些都可以轉換為有效的比特幣地址。但是計算其中有多少可以非常簡單。答案是 1/256^4。為什麼?
因為當我們生成比特幣地址時,我們所能改變的只是成熟的結果,它給了我們 20 個字節。其他 4 個字節只是校驗和。簡單的想法是我們可以有 2^192 個原始地址,其中只有 2^160 個是有效的,因為我們只能有 2^160 個有效的比特幣地址。這給了我們 1/256^4 的比率。
最後一部分:取我們所有範圍長度的總和,除以 256^4,這將是具有給定虛榮的所有可能的比特幣地址的數量。只需將 2^160 除以這個數字,這就是結果。
讓我們通過發現 A 前綴的困難來說明它。
A 只是 9。好的,讓我們找出所有範圍,這將給我們 9 作為商。522 - 579 30276 - 33639 1756008 - 1951119 …….我們必須去和去,直到我們的數字的長度將不會達到24個字節(介意領先的00字節)…….. 41735950621193504130037849728691446275009901558579068928 - 46373278467992782366708721920768273638899890620643409919
這兩個數字的長度都是 24 字節。這是我們的第一個範圍。接下來是
2420685136029223239542195284264103883950574290397585997824 - 2689650151143581377269105871404559871056193655997317775359
這個數字也是 24 字節長。
下一對將是 140399737889694947893447326487318025269133308843059987873792 和 155999708766327719881608140541464472521259232047844430970879
兩者都大於 2^192,所以現在我們必須停下來。讓我們總結一下我們的結果:
46373278467992782366708721920768273638899890620643409919 - 41735950621193504130037849728691446275009901558579068928 + 2689650151143581377269105871404559871056193655997317775359 - 2420685136029223239542195284264103883950574290397585997824 = 273602342961157415963581459332532814469509354661796118526
這就是我們可以擁有多少個可能的原始地址。但不要忘記將其除以 156^4 並得到: 63703009616853067642911677093369144589991624155
這就是我們可以擁有多少個可能的比特幣地址。現在只需將 2^160 除以這個數字,結果將是22
這是前綴“A”或“1A”的困難。現在讓我們談談一些特殊情況。在使用範圍時,您必須檢查的是:
- 長度。範圍的長度必須等於原始地址的長度,並且您必須計算所有合適的範圍。
- **2^192。**如果範圍的末尾大於 2^192,則必須從頂部按 2^192 的值剪切此範圍 - 原始地址不能大於 2^192。還要記住,範圍的開頭必須始終小於 2^192(如果不是,那沒有任何意義)。
特殊情況怎麼辦?喜歡以多個“1”開頭的模式?這有點棘手,但不是很複雜。“1”是 base58 中的一個特殊情況,因為它等於 0。這意味著,當開頭有一些“1”時 - 所有這些字節都必須歸零並且不能使用。所以我們的原始地址,如果我們想以兩個“1”開頭,必須在開頭有兩個零字節。就像 0000XXXX…. 如果我們想要 111,我們必須在開頭留下 3 個字節作為零字節,依此類推。
這是什麼意思?每個 1 將從我們的原始地址中減少一個字節,因此它將我們可能最大的原始地址數的長度減少 8 位或一個字節。這將使查找難度增加 256 倍,並且縮短一個字節。
就像如果我們想在開始時有 11 個字節,我們將只有 23 個字節來生成我們的範圍,如果我們想要有 1111 個字節,它將只給我們 21 個字節。所以我們的範圍會更小,難度會更高。顯然,如果我們在模式中有超過 19 個“1”,則不可能找到任何地址,因為我們必須為成熟結果留下一些東西:)
如果模式僅以 111 開頭,只需計算“1”的數量並假設範圍的開頭為 0,範圍的結尾為 2^(200-8*number_of_1’s),因為我們只有 200 位用於原始地址,其中一些在我們的 111(1)-like 模式的情況下必須歸零。
如果我們有像 11(1)X(X) 這樣的模式,其中 X 是非零符號,只需將最大可能的原始地址縮短為等於 1 的字節數的字節數並進行普通計算。