Кодирование и декодирование чисел по алгоритму Base58
Base58 - вариант кодирования чисел в виде буквенно-цифрового текста на основе цифр и символов латинского алфавита. Алфавит Base58, как можно догадаться из названия, содержит 58 символов. Base58 был разработан для передачи данных и уменьшения количества ошибок у пользователей, которые вручную вводят данные на основе распечатанного текста или фотографии, то есть без возможности машинного копирования и вставки. Так, к примеру, Base58 используется для кодирования идентификаторов кошельков Bitcoin, для создания коротких ссылок на фотохостингах и т.п. В отличие от кодирования Base64, позволяющего работать с неограниченными объемами двоичных данных, Base58 предназначен для кодирования только одиночных числовых значений.Согласно спецификации, в алфавит Base58 не входят буквенно-цифровые символы, которые имеют сходное написание и могут неоднозначно восприниматься человеком (например, буква "О" и цифра "0"), а также символы, используемые при формировании URL. Вместе с тем, порядок следования символов в алфавите ничем не регламентирован, зависит только от сферы применения кодирования и может быть любым. Для этой статьи я выбрал следующий алфавит Base58:
Code (Assembler) : Убрать нумерацию
- alpha db '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
- alpha_len=$-alpha
Теперь переходим к функции кодирования. Из-за использования 32-битной математики, максимальное значение, доступное для кодирования, не может превышать 0xFFFFFFFFh
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------
- ; Кодирование числа по алгоритму Base58
- ;-----------------------------------------------------
- proc base58_encode dValue:DWORD, szOut:DWORD
- pusha
- mov edi,[szOut]
- mov eax,[dValue]
- mov ecx,alpha_len
- @@:
- xor edx,edx
- div ecx
- push eax
- mov al,byte [alpha+edx]
- stosb
- pop eax
- or eax,eax
- jnz @b
- stosb
- popa
- ret
- endp
А вот функция для обратного декодирования строки из Base58 в числовое значение:
Code (Assembler) : Убрать нумерацию
- ;-----------------------------------------------------
- ; Декодирование строки в число по алгоритму Base58
- ;-----------------------------------------------------
- proc base58_decode szIn:DWORD
- locals
- res dd ?
- endl
- pusha
- mov esi,[szIn]
- mov ebx,1
- mov [res],0
- @@:
- lodsb
- or al,al
- jz @f
- mov edi,alpha
- mov ecx,alpha_len
- repne scasb
- inc ecx
- neg ecx
- add ecx,alpha_len
- mov eax,ebx
- imul eax,ecx
- add [res],eax
- imul ebx,alpha_len
- jmp @b
- @@:
- popa
- ; Результат
- mov eax,[res]
- ret
- endp
В приложении примеры программ с исходными текстами для кодирования чисел по алгоритму Base58 и для декодирования полученных строк обратно в числа.
Просмотров: 3939 | Комментариев: 4
Метки: Assembler, полезные функции
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(10.02.2020 в 17:10):
Нет, и этой темой вообще не интересуюсь.
cTpaHHuK
(10.02.2020 в 17:02):
ManHunter, а у тебя нет примера функций на асме как кодировать , декодировать base58 адреса и приватные ключи в биткоине?
ManHunter
(25.02.2019 в 08:15):
Так он для чисел и предназначен, чтобы в ссылке указывать не /article/1234, а что-то типа /article/fjR. Про BigInt согласен.
DimitarSerg
(25.02.2019 в 05:59):
Хм, странно работает, оно получается кодирует именно hex-value (точнее даже dec), а не ascii, но и в этом случае работает не то чтобы криво, но не по стандарту, пример: у тебя 12 кодируется в d, но в моем коде d декодируется в 0x0C.
А так то все эти бейзы реализовываются одной функцией с передачей в ней длинны алфавита и, собственно, самого алфавита, нюанс - использовать либу для больших чисел нужно, если язык из коробки не поддерживает.
А так то все эти бейзы реализовываются одной функцией с передачей в ней длинны алфавита и, собственно, самого алфавита, нюанс - использовать либу для больших чисел нужно, если язык из коробки не поддерживает.
Добавить комментарий
Заполните форму для добавления комментария