gpt4 book ai didi

c# - 将比特币 Base58 地址解码为字节数组

转载 作者:太空狗 更新时间:2023-10-29 21:42:34 28 4
gpt4 key购买 nike

我正在尝试将比特币地址从 Base58 字符串解码为字节数组,为此我将用 C++ 编写的 Satoshi 存储库 ( https://github.com/bitcoin/bitcoin/blob/master/src/base58.cpp ) 中的原始函数重写为 C#(我正在使用)。

原始代码

static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

bool DecodeBase58(const char *psz, std::vector<unsigned char>& vch) {
// Skip leading spaces.
while (*psz && isspace(*psz))
psz++;
// Skip and count leading '1's.
int zeroes = 0;
while (*psz == '1') {
zeroes++;
psz++;
}
// Allocate enough space in big-endian base256 representation.
std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up.
// Process the characters.
while (*psz && !isspace(*psz)) {
// Decode base58 character
const char *ch = strchr(pszBase58, *psz);
if (ch == NULL)
return false;
// Apply "b256 = b256 * 58 + ch".
int carry = ch - pszBase58;
for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) {
carry += 58 * (*it);
*it = carry % 256;
carry /= 256;
}
assert(carry == 0);
psz++;
}
// Skip trailing spaces.
while (isspace(*psz))
psz++;
if (*psz != 0)
return false;
// Skip leading zeroes in b256.
std::vector<unsigned char>::iterator it = b256.begin();
while (it != b256.end() && *it == 0)
it++;
// Copy result into output vector.
vch.reserve(zeroes + (b256.end() - it));
vch.assign(zeroes, 0x00);
while (it != b256.end())
vch.push_back(*(it++));
return true;
}

我重写的c#版本

 private static string Base58characters = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
public static bool Decode(string source, ref byte[] destination)
{
int i = 0;
while (i < source.Length)
{
if (source[i] == 0 || !Char.IsWhiteSpace(source[i]))
{
break;
}
i++;
}
int zeros = 0;
while (source[i] == '1')
{
zeros++;
i++;
}
byte[] b256 = new byte[(source.Length - i) * 733 / 1000 + 1];
while (i < source.Length && !Char.IsWhiteSpace(source[i]))
{
int ch = Base58characters.IndexOf(source[i]);
if (ch == -1) //null
{
return false;
}
int carry = Base58characters.IndexOf(source[i]);
for (int k = b256.Length - 1; k > 0; k--)
{
carry += 58 * b256[k];
b256[k] = (byte)(carry % 256);
carry /= 256;
}
i++;
}
while (i < source.Length && Char.IsWhiteSpace(source[i]))
{
i++;
}
if (i != source.Length)
{
return false;
}
int j = 0;
while (j < b256.Length && b256[j] == 0)
{
j++;
}
destination = new byte[zeros + (b256.Length - j)];
for (int kk = 0; kk < destination.Length; kk++)
{
if (kk < zeros)
{
destination[kk] = 0x00;
}
else
{
destination[kk] = b256[j++];
}
}
return true;
}

我用于从字节数组转换为 HexString 的函数

public static string ByteArrayToHexString(byte[] source)
{
return BitConverter.ToString(source).Replace("-", "");
}

为了测试是否一切正常,我使用了在此处在线找到的测试用例 (https://github.com/ThePiachu/Bitcoin-Unit-Tests/blob/master/Address/Address%20Generation%20Test%201.txt)。好消息是这个测试的 97% 都正确通过了,但是 3 有一点错误,我不知道它是从哪里来的。所以我想问你的是指出这些测试可能出错的地方,或者我在重写时哪里出错了。提前谢谢你。

出现错误的测试用例是1、21和25。

1.输入:16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM输出:000966776006953D5567439E5E39F86A0D273BEED61967F6应该:00010966776006953D5567439E5E39F86A0D273BEED61967F6

21。输入:1v3VUYGogXD7S1E8kipahj7QXgC568dz1输出:0008201462985DF5255E4A6C9D493C932FAC98EF791E2F22应该:000A08201462985DF5255E4A6C9D493C932FAC98EF791E2F22

25。输入:1axVFjCkMWDFCHjQHf99AsszXTuzxLxxg输出:006C0B8995C7464E89F6760900EA6978DF18157388421561应该:00066C0B8995C7464E89F6760900EA6978DF18157388421561

最佳答案

在你的 for 循环中:

for (int k = b256.Length - 1; k > 0; k--)

循环条件应为 k >= 0,这样您就不会跳过 b256 中的第一个字节。

关于c# - 将比特币 Base58 地址解码为字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25855062/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com