Base58
Base58 биткойн: азбука от 58 знака без 0, O, I и l за старите адреси, WIF ключовете и разширените ключове. Вижте как работи.
От Dimitar Zurnov · Обновено на 4 ноември 2026
Адаптирано от Learn Me a Bitcoin на Greg Walker.
Base58 е начин да запишете голямо число с 58 знака. Биткойн го ползва за старите адреси, за WIF частните ключове и за разширените ключове. Азбуката няма 0, O, I и l, които в много шрифтове си приличат. Няма и символи, така че низът се копира и поставя без проблем.
Какви знаци използва Base58?
Азбуката има 58 знака, в този ред:
123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
Тя започва от 62-те букви и цифри на стандартния буквено-цифров набор и премахва четири: 0, O, I и l. Сатоши обяснява избора си в коментар в първата версия, в base58.h, огледало на Bitcoin v0.1. Знаците, които си приличат, водят до грешки. Имейл програмите чупят реда само на места с пунктуация, а низ от само букви и цифри се маркира цял с двоен клик.
Какво означава „base 58“?
Основата е броят на символите, които една система използва. Обикновените числа са в основа 10, с десет цифри от 0 до 9. Шестнадесетичната система е в основа 16. Base58 използва 58 символа, затова записва същото число с по-малко знаци. Числото 9999 е 270f в шестнадесетичната система и 3yQ в Base58. Трите записа означават една и съща стойност. Различават се само символите.
Как се кодира число в Base58?
Делете числото на 58 отново и отново. Всеки остатък е индекс в азбуката, така че дава един знак. Спрете, когато частното стане нула. Четете знаците от последния остатък към първия.
Краткият скрипт по-долу върши същата работа. Знакът 1 в началото на резултата идва от водещите нулеви байтове, които обяснява следващият раздел.
ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
def base58_encode(data: bytes) -> str:
n = int.from_bytes(data, "big")
out = ""
while n > 0:
n, r = divmod(n, 58) # остатъкът е следващият знак
out = ALPHABET[r] + out
# всеки водещ нулев байт става "1"
return "1" * (len(data) - len(data.lstrip(b"\x00"))) + out
def base58_decode(text: str) -> bytes:
n = 0
for c in text:
n = n * 58 + ALPHABET.index(c)
body = n.to_bytes((n.bit_length() + 7) // 8, "big")
return b"\x00" * (len(text) - len(text.lstrip("1"))) + body
print(base58_encode(bytes.fromhex("001fe032088d648e925f15a24a0cf6a1e80f01bf9194686373")))
# 13uYXKWq8VoZgQApSxTXHPtYDs1m1xGi4z
print(base58_decode("13uYXKWq8VoZgQApSxTXHPtYDs1m1xGi4z").hex())
# 001fe032088d648e925f15a24a0cf6a1e80f01bf9194686373
Как се декодира низ в Base58?
Декодирането върви в обратна посока. Всеки знак дава индекс от 0 до 57. Умножете индекса по 58, повдигнат на степен, равна на позицията на знака, броена отдясно от нула, и съберете резултатите. За BukQL изчислението е:
L = 19 × 58^0 = 19
Q = 23 × 58^1 = 1334
k = 43 × 58^2 = 144652
u = 52 × 58^3 = 10145824
B = 10 × 58^4 = 113164960
---------
123456789
Функцията base58_decode от скрипта по-горе стига до същата сума по схемата на Хорнер. Тя умножава текущата сума по 58 за всеки знак, отляво надясно, и добавя следващия индекс. Резултатът е същата сума.
Какво става с водещите нули?
Числото не се променя, когато отпред добавите нули. Затова кодировчик, който работи само с числото, би загубил нулевите байтове в началото на данните. Биткойн избягва това, като превръща всеки водещ нулев байт (00) в знака 1. Декодерът превръща всеки водещ знак 1 обратно в нулев байт.
Затова P2PKH адресът започва с 1. Данните му започват с байта за версия 00. P2SH адресът започва с 3, защото байтът му за версия е 05.
Кои префикси дават кой първи знак?
Биткойн добавя байт за версия в началото на данните, преди да ги кодира. Байтът за версия определя първия знак на резултата, така че по поглед можете да разберете какъв е низът.
| Префикс в основната мрежа | Първи знак | Какво кодира |
|---|---|---|
00 |
1 | P2PKH адрес |
05 |
3 | P2SH адрес |
80 |
5, K или L | WIF частен ключ |
0488ADE4 |
xprv | Разширен частен ключ |
0488B21E |
xpub | Разширен публичен ключ |
| Префикс в тестовата мрежа | Първи знак | Какво кодира |
|---|---|---|
6F |
m или n | P2PKH адрес |
C4 |
2 | P2SH адрес |
EF |
c или 9 | WIF частен ключ |
04358394 |
tprv | Разширен частен ключ |
043587CF |
tpub | Разширен публичен ключ |
WIF ключ, чийто публичен ключ е некомпресиран, започва с 5. Ако публичният ключ е компресиран, низът започва с K или L. Страницата за WIF обяснява флага, който прави разликата.
Какво е Base58Check?
Base58Check е Base58 с предварително добавена контролна сума. Към данните се добавят първите 4 байта от двойния SHA-256 хеш, а после всичко се кодира в Base58. Контролната сума хваща повечето грешки при писане, преди низът да е използван.
Адресът на примерния ключ е построен така. Данните са байтът за версия 00 и 20-байтовият хеш на публичния ключ. Контролната сума е 94686373. Кодирането на 25-те байта в Base58 дава 13uYXKWq8VoZgQApSxTXHPtYDs1m1xGi4z, първият резултат, който печата скриптът по-горе.
Къде се ползва Base58?
- Стари адреси. P2PKH адресите започват с
1, а P2SH адресите с3. Вижте адрес. - WIF частни ключове. Низът WIF е частен ключ в Base58Check.
- Разширени ключове. Низовете
xprvиxpubза HD портфейли също са в Base58Check.
SegWit и Taproot адресите не ползват Base58. Те ползват bech32, който има по-силна контролна сума и никога не смесва главни и малки букви.
Обобщение
Base58 записва големи числа с 58 знака. Пропуска 0, O, I и l, затова е лесен за четене и копиране. Няколко байта за версия определят първия знак, а контролна сума пази целия низ. Никога не поставяйте частен ключ, в WIF или в друг вид, в уебсайт. Сайт, който е видял ключа, може да запази копие.
Източници: base58.cpp на Bitcoin Core е референтната реализация, а страницата Base58Check encoding в Bitcoin Wiki изброява префиксите.
В този раздел: Ключове и адреси
Целият курс „Биткойн от нулата“
Нещо не изглежда наред? Кажете ни