與 P2PKH 不同,為什麼 P2SH 似乎永遠不會小於 34 個字元?
為什麼 P2SH 發票地址的 base58 似乎永遠不會小於 34 個字元;不像P2PKH發票地址的base58,其中33個字元很常見?
比特幣維基告訴(格式和強調我的):
一些比特幣發票地址可以少於 34 個字元(少
至 26 個)並且仍然有效。**很大一部分比特幣發票
地址只有 33 個字元**,有些發票可能更短。
從技術上講,每張比特幣發票都代表一個數字。這些較短
的發票之所以有效,僅僅是因為它們代表恰好以
零開頭的數字,並且當省略零時,編碼的發票
地址會變短。
但是在 P2PKH 發票地址的 base58 中,長度 33 比 P2SH 的 base58 頻繁得多。為什麼會這樣?
因為 Base58 首字母
1
s 攜帶 8 位數據,但 P2SH 地址不能用帶有首字母1
s 的字元串表示,所以它以它開頭3
,與所有其他情況和字元一樣,編碼 5.86 位數據。由於相同的位數編碼更少的字節,所以 P2SH 需要更多的位數。P2PKH 網路字節為 0x00,其餘為散列和校驗和。如果雜湊也以 0 位開頭,P2PKH 地址將利用初始 1 的效率,而 P2SH 以 0x05 開頭,因此即使是 1,後面的數字也不是初始 1,它們不會受到我上面描述的效率快捷方式的影響。
更新:
Base58Check 算法如下:
序列化後的數據為“網路字節”+“20字節雜湊”+“4字節校驗和”
校驗和根本不會改變地址長度。網路字節和散列。
序列化的數據採用以下方式編碼:
- Count initial 0x00s and discard them from the serialized data
例如,對於主網 P2PKH 地址(這些地址具有網路字節 = 0x00),如果 20 字節雜湊以 0x 開頭
00000a...
,則有 3 個初始零。對於其他地址,例如主網 P2SH(網路字節:0x05),不需要考慮雜湊,初始零的數量為零。- Base-convert the rest
可以通過長除法計算的標準數學運算。簡單的計算方法是將二進製字節數組表示為 BigNumber 並考慮餘數序列。
一個八進制數字對應於 3 個二進制數字,因為 log_2 (8) = 3。同樣,一個 Base58 數字對應於 log_2 (58) = 5.86 個二進制數字(對於 Base64,略小於 6 個數字)。這是鹼基轉換的結果。
然而,如果有初始 0,當我們使用它們時,我們會從要讀取和序列化的字節中減去 8 位,而不是 5.86。這是中本聰決定以更高的地址長度差異(25-34 個字元)為代價允許更短地址的結果
第一個字節是網路字節。當它不為零時(對於 P2SH,它總是如此!)則沒有初始零,結果是 100% 源自沒有初始零快捷方式的基本轉換。就像六位二進制數總是有 2 個十進制數字一樣,所有 P2SH 主網地址都有 34 個字元。
注意:7 位二進制數可以有 2 位或 3 位十進制數。根據網路字節的不同,地址編碼也可能出現一位數的變化。主網 P2SH 不是這種情況,它總是有 34 個字節。我知道這一點,因為Base58
5*256^24
和in 都有 34 位數字。6*256^24 - 1
並且 P2PKH 變化不止一位,因為正如 Pieter Wuille 評論的那樣,二進制 P2SH 的序列化數據具有固定的位數,而 P2PKH 的序列化數據可以有許多初始零(以及如何使用這些零可以與省略它們進行比較)。