You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Base58Check格式转换异常:编码后解码提示校验和无效求助

Base58Check编码解码校验和错误问题修复

问题背景

尝试将指定整数通过Base58Check编码为字符串,但解码时始终提示「无效校验和」错误,涉及编码、解码、私钥生成三类代码均存在逻辑问题。使用的整数为:111383925596674021496745350149385052040158942814438962455769092527167857754112

原编码代码

import hashlib
import base58

code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

def convert_bytes_to_base58check(hash_result, num_leading_zero_bytes):
    x = int.from_bytes(hash_result, byteorder="big")
    output_string = ""
    while x > 0:
        x, remainder = divmod(x, 58)
        output_string += code_string[remainder]
    output_string += code_string[0] * num_leading_zero_bytes
    return output_string[::-1]

my_integer = 111383925596674021496745350149385052040158942814438962455769092527167857754112
my_hex_string = hex(my_integer)[2:]
if len(my_hex_string) % 2 != 0:
    my_hex_string = "0" + my_hex_string
my_bytes = bytes.fromhex(my_hex_string)
my_hash = hashlib.sha256(hashlib.sha256(my_bytes).digest()).digest()
output_string = convert_bytes_to_base58check(my_hash, 0)
print(output_string)

原解码代码

import base58
code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

def convert_bytes_to_big_integer(data):
    return int.from_bytes(data, byteorder='big')

def encode_base58check(hash_result, num_leading_zero_bytes):
    x = convert_bytes_to_big_integer(hash_result)
    output_string = ""
    
    while x > 0:
        x, remainder = divmod(x, 58)
        output_string += code_string[remainder]
    
    output_string += code_string[0] * num_leading_zero_bytes
    return output_string[::-1]

my_string = 'GTbisRUFDyw71dQcDXfMbYK6hMQ1EcnTvTmvGa5LodBp'
my_bytes = base58.b58decode_check(my_string)
my_hash = my_bytes[:-4]
num_leading_zero_bytes = my_bytes[-1]
output_string = encode_base58check(my_hash, num_leading_zero_bytes)
print(output_string)

原私钥生成代码

from bitcoin import *
import base58
def getPrivateKey(my_integer):
    print(type(my_integer))
    print("number = ",my_integer)
    public_key = privtopub(my_integer)
    uncompressed_address = pubtoaddr(public_key)
    compressed_public_key = compress(public_key)
    compressed_address = pubtoaddr(compressed_public_key)

    my_hex_string = hex(my_integer)[2:]
    print("hex_string = ",my_hex_string)

    if len(my_hex_string) % 2 != 0:
        my_hex_string = "0" + my_hex_string
    my_bytes = bytes.fromhex(my_hex_string)
    my_bytes_with_prefix = b"\x80" + my_bytes
    my_bytes_with_prefix_and_checksum = my_bytes_with_prefix + b"\x01" + bin_sha256(bin_sha256(my_bytes_with_prefix))[:4]
    my_private_key = base58.b58encode(my_bytes_with_prefix_and_checksum)
    print(my_private_key)

问题分析

  1. 编码代码核心错误:

    • 错误地将双重SHA256的哈希结果直接编码,而非将**原始数据+校验和(哈希前4字节)**的组合体进行Base58编码。
    • 前导零字节处理逻辑颠倒,导致编码结果无法正确对应原始数据的前导零。
  2. 解码代码核心错误:

    • 误解base58.b58decode_check的返回值:该函数返回的是已验证校验和并去除校验和后的原始数据,而非带校验和的完整数据,因此my_bytes[:-4]是错误操作。
    • 从my_bytes[-1]提取前导零字节数的逻辑完全不符合Base58Check规范。
  3. 私钥生成代码核心错误:

    • 计算校验和时仅基于前缀+私钥,而非前缀+私钥+压缩标记(0x01)的完整数据,导致校验和不匹配。

修复后的代码

修复版编码代码

import hashlib

code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

def encode_base58check(data):
    # 计算校验和:双重SHA256取前4字节
    checksum = hashlib.sha256(hashlib.sha256(data).digest()).digest()[:4]
    # 拼接原始数据与校验和
    data_with_checksum = data + checksum
    # 统计前导零字节数
    num_leading_zeros = 0
    while num_leading_zeros < len(data_with_checksum) and data_with_checksum[num_leading_zeros] == 0:
        num_leading_zeros += 1
    # 转换为大整数
    x = int.from_bytes(data_with_checksum, byteorder="big")
    output = []
    while x > 0:
        x, remainder = divmod(x, 58)
        output.append(code_string[remainder])
    # 补充前导零对应的Base58前缀字符
    output.extend([code_string[0]] * num_leading_zeros)
    # 反转得到最终编码结果
    return ''.join(reversed(output))

# 目标整数
my_integer = 111383925596674021496745350149385052040158942814438962455769092527167857754112
# 转换为32字节标准私钥格式
my_bytes = my_integer.to_bytes(32, byteorder='big')

# 编码整数本身(无前缀)
encoded_integer = encode_base58check(my_bytes)
print("编码后的整数:", encoded_integer)

# 编码压缩格式私钥(带0x80前缀和0x01压缩标记)
compressed_privkey_data = b"\x80" + my_bytes + b"\x01"
encoded_compressed_privkey = encode_base58check(compressed_privkey_data)
print("压缩私钥编码结果:", encoded_compressed_privkey)

修复版解码代码

import hashlib

code_string = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

def decode_base58check(s):
    # 将Base58字符串转换为大整数
    x = 0
    for c in s:
        x = x * 58 + code_string.index(c)
    # 转换为字节(自动补位)
    data_with_checksum = x.to_bytes((x.bit_length() + 7) // 8, byteorder='big')
    # 统计Base58字符串中的前缀零字符数
    num_leading_zeros = 0
    while num_leading_zeros < len(s) and s[num_leading_zeros] == code_string[0]:
        num_leading_zeros += 1
    # 补上前导零字节
    data_with_checksum = b'\x00' * num_leading_zeros + data_with_checksum
    # 拆分原始数据与校验和
    data = data_with_checksum[:-4]
    checksum = data_with_checksum[-4:]
    # 验证校验和
    expected_checksum = hashlib.sha256(hashlib.sha256(data).digest()).digest()[:4]
    if checksum != expected_checksum:
        raise ValueError("无效校验和")
    return data

# 待解码字符串
my_string = 'GTbisRUFDyw71dQcDXfMbYK6hMQ1EcnTvTmvGa5LodBp'
try:
    decoded_data = decode_base58check(my_string)
    print("解码后原始数据(十六进制):", decoded_data.hex())
    # 若为压缩私钥,提取原始整数
    if len(decoded_data) == 34 and decoded_data[0] == 0x80 and decoded_data[-1] == 0x01:
        privkey_integer = int.from_bytes(decoded_data[1:-1], byteorder='big')
        print("提取的私钥整数:", privkey_integer)
except ValueError as e:
    print("解码失败:", e)

修复版私钥生成代码

from bitcoin import *
import hashlib
import base58

def getPrivateKey(my_integer):
    print("整数类型:", type(my_integer))
    print("私钥整数:", my_integer)
    # 生成公钥及地址
    public_key = privtopub(my_integer)
    uncompressed_address = pubtoaddr(public_key)
    compressed_public_key = compress(public_key)
    compressed_address = pubtoaddr(compressed_public_key)
    print("非压缩地址:", uncompressed_address)
    print("压缩地址:", compressed_address)

    # 转换为32字节标准私钥字节
    my_bytes = my_integer.to_bytes(32, byteorder='big')
    print("私钥十六进制:", my_bytes.hex())

    # 生成压缩私钥
    compressed_data = b"\x80" + my_bytes + b"\x01"
    compressed_checksum = hashlib.sha256(hashlib.sha256(compressed_data).digest()).digest()[:4]
    compressed_privkey = base58.b58encode(compressed_data + compressed_checksum).decode('utf-8')
    print("压缩私钥:", compressed_privkey)

    # 生成非压缩私钥
    uncompressed_data = b"\x80" + my_bytes
    uncompressed_checksum = hashlib.sha256(hashlib.sha256(uncompressed_data).digest()).digest()[:4]
    uncompressed_privkey = base58.b58encode(uncompressed_data + uncompressed_checksum).decode('utf-8')
    print("非压缩私钥:", uncompressed_privkey)

# 调用示例
my_integer = 111383925596674021496745350149385052040158942814438962455769092527167857754112
getPrivateKey(my_integer)

内容的提问来源于stack exchange,提问作者timp bill

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 09:49:55