Как кодировать строку в base58?
char (* text)[1][45+1];
text = calloc(5000,(130+1));
strcpy(0[*text],"sometext)");
теперь я хочу закодировать "sometext" в base58, однако я не знаю, как, и, как ни странно, нет ни одного примера BASE58 в C.
кодировка base58, которая меня интересует, использует эти символы:
123456789abcdefghijkmnopqrstuvwxyzabcdefghjklmnpqrstuvwxyz
Он был оптимизирован, чтобы уменьшить риск неправильного чтения, поэтому 0 и " O " исчезли, например.
П. С. Не обращайте внимания на странное распределение и объявление переменных, я экспериментировал.
5 ответов
вы не должны кодировать строки, вы должны кодировать чисел.
Если вы начинаете со строки, вы должны сначала решить, как интерпретировать ее как целое число (может быть base128 или что-то еще), а затем перекодировать в base58.
Сатоши имеет ссылочную реализацию (https://github.com/bitcoin/bitcoin/blob/master/src/base58.h)
однако он использует для этого класс утилиты bignum, и это на C++. Если у вас есть доступ к библиотеке bignum, вы просто продолжаете делить на 58, пока число не будет разбито. Если у вас нет библиотеки bignum, AFAIK вам не повезло.
вот реализация в PHP для больших чисел, которые я создал для Amithings, помимо целых чисел (Integer ->http://php.net/manual/en/language.types.integer.php).
например, попробуйте пример ниже (Не забудьте передать свой ID функции в строковом формате. Используйте функцию PHP strval ()):
$number = '123456789009876543211234567890';
$result = base58_encode($number);
echo('Encoded: ' . $result . '<br>');
echo('Decoded: ' . base58_decode($result) . '<br>');
важно: вы можете подумать об изменении этой процедуры, включив какой-то ключ / пароль / шифрование, чтобы гарантировать, что другие не могут расшифруйте идентификаторы базы данных.
function base58_encode($input)
{
$alphabet = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
$base_count = strval(strlen($alphabet));
$encoded = '';
while (floatval($input) >= floatval($base_count))
{
$div = bcdiv($input, $base_count);
$mod = bcmod($input, $base_count);
$encoded = substr($alphabet, intval($mod), 1) . $encoded;
$input = $div;
}
if (floatval($input) > 0)
{
$encoded = substr($alphabet, intval($input), 1) . $encoded;
}
return($encoded);
}
function base58_decode($input)
{
$alphabet = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
$base_count = strval(strlen($alphabet));
$decoded = strval(0);
$multi = strval(1);
while (strlen($input) > 0)
{
$digit = substr($input, strlen($input) - 1);
$decoded = bcadd($decoded, bcmul($multi, strval(strpos($alphabet, $digit))));
$multi = bcmul($multi, $base_count);
$input = substr($input, 0, strlen($input) - 1);
}
return($decoded);
}
вот реализация, которая кажется чистой c
.
https://github.com/trezor/trezor-crypto/blob/master/base58.c
мой простой код с библиотекой Crypto++ :
string base58_encode(Integer num, string vers)
{
string alphabet[58] = {"1","2","3","4","5","6","7","8","9","A","B","C","D","E","F",
"G","H","J","K","L","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c",
"d","e","f","g","h","i","j","k","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
int base_count = 58; string encoded; Integer div; Integer mod;
while (num >= base_count)
{
div = num / base_count; mod = (num - (base_count * div));
encoded = alphabet[ mod.ConvertToLong() ] + encoded; num = div;
}
encoded = vers + alphabet[ num.ConvertToLong() ] + encoded;
return encoded;
}
Это только для криптовалютных кошельков. string можно изменить для других задач.