import hashlib
import ecdsa
from base58 import b58encode_check
xor_masks = {
68: 未知,
67: 0b0001100111100000011110111001010001111100110101111010011111001010001,
66: 0b010111110011010001001010001011000011010100101000011100101000010001,
65: 0b00101011111000111010011101100101011111010010011011001011110011000,
64: 0b0000100011111010111000001101100001001111011011101110110100101011,
63: 0b000001100110001101000010000001001010011001100001001011111110111,
62: 0b00100111000010101010111110000101001001111011100101010000010001,
61: 0b0110000110110100101011100100010111101000010011011011011111001,
60: 0b000000111111100001011110011111011010110010011000010001000001,
59: 0b00010110110100100110100010001111000001101010100101110110000,
58: 0b0100111001100010100100011110101101111001110110010111011110,
57: 0b000010100110110100011011011111000011010100010100111100011,
56: 0b01100010111001110100100111000101001110110000000000100000,
55: 0b0010101010000011110000001100100100110000001111011101011,
54: 0b011100100100000100100100101010010100101110000010111100,
53: 0b00111111110000111011100011011100000011100110110010011,
52: 0b0001000001010001111010011011001101000110000111000011,
51: 0b000101011111000111101011110010111111111011000101011,
50: 0b01110101000010101111000011110100010110110010101011,
49: 0b0100010111110100010010100111111101010000010110010,
48: 0b010100100001100100101000001100011100010001100100,
47: 0b00100110010100111101111010010101100001101000101,
46: 0b100010011111001111100011101110010101010111011,
45: 0b11011101000000110101111010111100001111111010,
44: 0b11111110101001100101001011100101001110000,
43: 0b10100001011000100110110000011101001101110,
42: 0b10101110111011110001110100111001001110000,
41: 0b01010110001111001011001010011001110100100,
40: 0b1011001010001101101101100110000101001,
39: 0b011010010100000011111001111110000010110,
38: 0b01110111000111110100000101001100101111,
37: 0b0100010101000100010101001010101101100,
36: 0b011000100001011111011111010110000011,
35: 0b01101010001001011011110111010001111,
34: 0b0010110101100110100110111011100010,
33: 0b1010110100100110101011100100111,
32: 0b1000111100111010101100111010001,
31: 0b10101100000001100010111000,
30: 0b10011010110011001010011011,
29: 0b1000000111011010101011100001,
28: 0b10011011101001001100010111,
27: 0b1010100111100011110001010,
26: 0b00101111111100110110010001,
25: 0b1011010000100011010,
24: 0b1000111101010111111011,
23: 0b1010101001000110101101,
22: 0b100100001101111110000,
21: 0b1000101101011001011,
20: 0b00101101001110101010,
19: 0b101000101101100000,
18: 0b1111011111110010,
17: 0b1000100110110000,
16: 0b11011011001001,
15: 0b1011100001100,
14: 0b1011011001111,
13: 0b101110011111,
12: 0b10110000100,
11: 0b1101111100,
10: 0b111111101,
9: 0b101100,
8: 0b11111,
7: 0b110011,
6: 0b1110,
5: 0b1010,
4: 0b111,
3: 0b0,
2: 0b0,
1: 0b0
}
def private_key_to_hex(private_key_int):
return private_key_int.to_bytes(32, byteorder='big').hex()
def private_key_to_address(private_key_int):
sk = ecdsa.SigningKey.from_string(
private_key_int.to_bytes(32, byteorder='big'),
curve=ecdsa.SECP256k1
)
vk = sk.get_verifying_key()
x_str = vk.to_string()[:32]
y_parity = (vk.to_string()[-1] & 1) + 2
compressed_public_key = bytes([y_parity]) + x_str
sha256 = hashlib.sha256(compressed_public_key).digest()
ripemd160 = hashlib.new('ripemd160', sha256).digest()
address = b58encode_check(b'\x00' + ripemd160)
return address.decode()
def generate_keys(puzzle, start_hex=None, end_hex=None, target_address=None):
if puzzle == 68:
if not all([start_hex, end_hex, target_address]):
return None, None, "需要提供起始值、结束值和目标地址"
try:
start = int(start_hex, 16)
end = int(end_hex, 16)
except ValueError:
return None, None, "十六进制值无效"
if start > end:
return None, None, "起始值必须小于等于结束值"
# 限制搜索范围不超过 256 位
max_value = (1 << 256) - 1
start = max(start, 0)
end = min(end, max_value)
for private_key in range(start, end + 1):
address = private_key_to_address(private_key)
print(f"\r 当前尝试: {private_key_to_hex(private_key)} 地址: {address}",
end='')
if address == target_address:
print("\n 匹配成功!")
return (private_key_to_hex(private_key), address, None)
return (None, None, "未找到匹配的地址")
else:
if puzzle not in xor_masks:
return None, None, "缺少 XOR 掩码"
puzzle_end = (1 << puzzle) - 1
private_key = puzzle_end ^ xor_masks[puzzle]
if private_key.bit_length() > 256:
private_key &= (1 << 256) - 1
return (private_key_to_hex(private_key),
private_key_to_address(private_key), None)
def user_interface():
print("比特币拼图密钥生成器")
print("输入拼图编号 (1-68) 或输入 q 退出")
while True:
user_input = input("\n>>> 请输入拼图编号: ").strip()
if user_input.lower() == 'q':
print("程序已退出")
break
try:
puzzle = int(user_input)
if puzzle == 68:
start_hex = input("请输入起始值 (HEX): ").strip()
end_hex = input("请输入结束值 (HEX): ").strip()
target_address = input("请输入目标地址: ").strip()
hex_key, address, error = generate_keys(
puzzle,
start_hex=start_hex,
end_hex=end_hex,
target_address=target_address
)
if error:
print(f"[!] 错误: {error}")
else:
if hex_key:
print(f"\n=== 匹配成功 ===")
print(f"私钥 (HEX): {hex_key}")
print(f"比特币地址: {address}")
else:
print("\n=== 搜索完成 ===")
print("未找到匹配的地址")
else:
if not 1 <= puzzle <= 68:
print("错误:编号需在 1-68 之间")
continue
hex_key, address, error = generate_keys(puzzle)
if error:
print(f"[!] 拼图 {puzzle} 错误: {error}")
else:
print(f"\n=== 拼图 {puzzle} 结果 ===")
print(f"私钥 (HEX): {hex_key}")
print(f"比特币地址: {address}")
except ValueError:
print("错误:请输入有效数字")
if __name__ == "__main__":
user_interface()