我如何base58编码一个字符串?

时间:2012-01-23 11:13:02

标签: c base

char (* text)[1][45+1];
text = calloc(5000,(130+1));
strcpy(0[*text],"sometext)");

现在我想将“sometext”编码为base58,但是,我不知道如何,奇怪的是,在C中没有一个BASE58的例子。

我感兴趣的base58编码使用这些符号:

  

123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ

它已被优化以减少误读的风险,因此0和'O'都消失了,例如。

P.S 不要介意变量的奇怪分配和声明,我正在试验。

5 个答案:

答案 0 :(得分:7)

Satoshi有参考实现(https://github.com/bitcoin/bitcoin/blob/master/src/base58.h

但是,他使用了一些实用的bignum类来实现它,而且它是用C ++编写的。如果您可以访问bignum库,则只需将58除以数字即可。如果你没有bignum图书馆,那么AFAIK就不算什么了。

答案 1 :(得分:6)

你不应该编码字符串,你应该编码整数

如果以字符串开头,则必须首先决定如何将其解释为整数(可能是base128或其他内容),然后在base58中重新编码。

答案 2 :(得分:3)

这是PHP中为Amithings创建的大数字的实现,超出整数(整数 - > 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>');

重要提示:您可以考虑通过添加某种密钥/密码/加密来更改此例程,以确保其他人无法解码您的数据库ID。

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);
}

答案 3 :(得分:1)

这是一个看似纯粹c的实现。

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

答案 4 :(得分:1)

我使用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;
  }
它只适用于加密货币钱包。可以为其他任务更改字符串。