#!/usr/bin/env python3
# Простіше не буває — працює в Python3 (Ideone)
import random, hashlib, sys
# порядок secp256k1 (щоб ключ був валідним)
N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
def gen_priv():
while True:
k = random.getrandbits(256)
if 0 < k < N:
return k
def to_hex32(k): return format(k, '064x')
def to_bin256(k): return format(k, '0256b')
def base58_encode(b: bytes):
num = int.from_bytes(b, 'big')
if num == 0:
# усе байти нулі -> "1" за кожен нуль
return '1' * len(b)
s = ""
while num > 0:
num, r = divmod(num, 58)
s = B58[r] + s
# leading zeros -> '1'
n_pad = 0
for x in b:
if x == 0:
n_pad += 1
else:
break
return '1'*n_pad + s
def base58check(payload: bytes):
chk = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
return base58_encode(payload + chk)
def wif_from_int(k, compressed=True):
p = b'\x80' + k.to_bytes(32, 'big')
if compressed:
p += b'\x01'
return base58check(p)
def main():
# опційно: передай у argv кількість ключів, інакше 1
n = 1
if len(sys.argv) > 1:
try:
n = max(1, int(sys.argv[1]))
except:
n = 1
for i in range(n):
priv = gen_priv()
print("=== Key #{} ===".format(i+1))
print("Hex (32 bytes):", to_hex32(priv))
print("Dec:", priv)
print("Bin (256-bit):", to_bin256(priv))
print("WIF (compressed):", wif_from_int(priv, True))
print()
if __name__ == "__main__":
main()
IyEvdXNyL2Jpbi9lbnYgcHl0aG9uMwojINCf0YDQvtGB0YLRltGI0LUg0L3QtSDQsdGD0LLQsNGUIOKAlCDQv9GA0LDRhtGO0ZQg0LIgUHl0aG9uMyAoSWRlb25lKQppbXBvcnQgcmFuZG9tLCBoYXNobGliLCBzeXMKCiMg0L/QvtGA0Y/QtNC+0Logc2VjcDI1NmsxICjRidC+0LEg0LrQu9GO0Ycg0LHRg9CyINCy0LDQu9GW0LTQvdC40LwpCk4gPSAweEZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZFQkFBRURDRTZBRjQ4QTAzQkJGRDI1RThDRDAzNjQxNDEKQjU4ID0gIjEyMzQ1Njc4OUFCQ0RFRkdISktMTU5QUVJTVFVWV1hZWmFiY2RlZmdoaWprbW5vcHFyc3R1dnd4eXoiCgpkZWYgZ2VuX3ByaXYoKToKICAgIHdoaWxlIFRydWU6CiAgICAgICAgayA9IHJhbmRvbS5nZXRyYW5kYml0cygyNTYpCiAgICAgICAgaWYgMCA8IGsgPCBOOgogICAgICAgICAgICByZXR1cm4gawoKZGVmIHRvX2hleDMyKGspOiByZXR1cm4gZm9ybWF0KGssICcwNjR4JykKZGVmIHRvX2JpbjI1NihrKTogcmV0dXJuIGZvcm1hdChrLCAnMDI1NmInKQoKZGVmIGJhc2U1OF9lbmNvZGUoYjogYnl0ZXMpOgogICAgbnVtID0gaW50LmZyb21fYnl0ZXMoYiwgJ2JpZycpCiAgICBpZiBudW0gPT0gMDoKICAgICAgICAjINGD0YHQtSDQsdCw0LnRgtC4INC90YPQu9GWIC0+ICIxIiDQt9CwINC60L7QttC10L0g0L3Rg9C70YwKICAgICAgICByZXR1cm4gJzEnICogbGVuKGIpCiAgICBzID0gIiIKICAgIHdoaWxlIG51bSA+IDA6CiAgICAgICAgbnVtLCByID0gZGl2bW9kKG51bSwgNTgpCiAgICAgICAgcyA9IEI1OFtyXSArIHMKICAgICMgbGVhZGluZyB6ZXJvcyAtPiAnMScKICAgIG5fcGFkID0gMAogICAgZm9yIHggaW4gYjoKICAgICAgICBpZiB4ID09IDA6CiAgICAgICAgICAgIG5fcGFkICs9IDEKICAgICAgICBlbHNlOgogICAgICAgICAgICBicmVhawogICAgcmV0dXJuICcxJypuX3BhZCArIHMKCmRlZiBiYXNlNThjaGVjayhwYXlsb2FkOiBieXRlcyk6CiAgICBjaGsgPSBoYXNobGliLnNoYTI1NihoYXNobGliLnNoYTI1NihwYXlsb2FkKS5kaWdlc3QoKSkuZGlnZXN0KClbOjRdCiAgICByZXR1cm4gYmFzZTU4X2VuY29kZShwYXlsb2FkICsgY2hrKQoKZGVmIHdpZl9mcm9tX2ludChrLCBjb21wcmVzc2VkPVRydWUpOgogICAgcCA9IGInXHg4MCcgKyBrLnRvX2J5dGVzKDMyLCAnYmlnJykKICAgIGlmIGNvbXByZXNzZWQ6CiAgICAgICAgcCArPSBiJ1x4MDEnCiAgICByZXR1cm4gYmFzZTU4Y2hlY2socCkKCmRlZiBtYWluKCk6CiAgICAjINC+0L/RhtGW0LnQvdC+OiDQv9C10YDQtdC00LDQuSDRgyBhcmd2INC60ZbQu9GM0LrRltGB0YLRjCDQutC70Y7Rh9GW0LIsINGW0L3QsNC60YjQtSAxCiAgICBuID0gMQogICAgaWYgbGVuKHN5cy5hcmd2KSA+IDE6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBuID0gbWF4KDEsIGludChzeXMuYXJndlsxXSkpCiAgICAgICAgZXhjZXB0OgogICAgICAgICAgICBuID0gMQoKICAgIGZvciBpIGluIHJhbmdlKG4pOgogICAgICAgIHByaXYgPSBnZW5fcHJpdigpCiAgICAgICAgcHJpbnQoIj09PSBLZXkgI3t9ID09PSIuZm9ybWF0KGkrMSkpCiAgICAgICAgcHJpbnQoIkhleCAoMzIgYnl0ZXMpOiIsIHRvX2hleDMyKHByaXYpKQogICAgICAgIHByaW50KCJEZWM6IiwgcHJpdikKICAgICAgICBwcmludCgiQmluICgyNTYtYml0KToiLCB0b19iaW4yNTYocHJpdikpCiAgICAgICAgcHJpbnQoIldJRiAoY29tcHJlc3NlZCk6Iiwgd2lmX2Zyb21faW50KHByaXYsIFRydWUpKQogICAgICAgIHByaW50KCkKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CiAgICBtYWluKCkK