Как мне base58 кодировать строку? - PullRequest
8 голосов
/ 23 января 2012
char (* text)[1][45+1];
text = calloc(5000,(130+1));
strcpy(0[*text],"sometext)");

Теперь я хочу закодировать «sometext» в base58, однако я не знаю, как, и, как ни странно, нет ни одного примера BASE58 в C.

Кодировка base58 Iменя интересуют следующие символы:

123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ

Это оптимизировано для уменьшения риска неправильного чтения, поэтому 0 и 'O' пропали,instance.

PS Не берите в голову странное распределение и объявление переменных, я экспериментировал.

Ответы [ 5 ]

7 голосов
/ 26 мая 2013

У Сатоши есть эталонная реализация (https://github.com/bitcoin/bitcoin/blob/master/src/base58.h)

Однако он использует для этого некоторый служебный класс bignum, и он находится в C ++. Если у вас есть доступ к библиотеке bignum, вы просто продолжаете делить на 58пока номер не будет разбит. Если у вас нет библиотеки bignum, AFAIK, вам не повезло.

6 голосов
/ 23 января 2012

Вы не должны кодировать строки , вы должны кодировать целые числа .

Если начинать со строки, вы должны сначала решить, какинтерпретировать его как целое число (может быть base128 или что-то еще), а затем перекодировать в base58.

3 голосов
/ 26 августа 2013

Вот реализация в PHP для больших чисел, которую я создал для Amithings, кроме целых чисел (Integer -> http://php.net/manual/en/language.types.integer.php).

Например, попробуйте пример ниже (Не забудьте передать свой идентификаторк функции в строковом формате. Используйте функцию 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);
}
1 голос
/ 04 января 2016

Мой простой код с библиотекой Crypto ++:

<code>
  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;
  }
Это только для криптовалютных кошельков.Строка может быть изменена для других задач.
1 голос
/ 25 января 2015

Вот реализация, которая кажется чистой c.

https://github.com/trezor/trezor-crypto/blob/master/base58.c
...