Private Key Tools

私钥 → P2PKH 压缩地址

经典的 1… 地址:把 33 字节压缩公钥哈希成 20 字节,前面加主网版本字节 0x00,后面加 4 字节双 SHA256 校验和,再做 Base58 编码。本页会把每个中间值都显示出来,让你逐字节看清构造过程。

本页会由它推导出压缩公钥再做哈希。允许 0x 前缀、空格与大写字母,不足 64 位会左补 0。数值必须落在 [1, n−1] 区间内。
还没有输入

请在上方输入内容后点击「转换」。不知道填什么?点「填入示例」即可载入占位符里的演示数据。

技术原理详解

本页计算了什么

输入一个 256 位私钥,输出一个经典的 1… 地址。地址并不是第二把密钥,也不是私钥的哈希 —— 它是 对压缩公钥的 20 字节承诺值做 Base58Check 编码的结果:

address = Base58Check( 0x00 ‖ RIPEMD160(SHA256(压缩公钥)) )
私钥 k→ k · G→ 33 字节压缩公钥→ SHA-256→ RIPEMD-160→ hash160(20 字节)→ 0x00 ‖ hash160 ‖ 校验和→ 1… 地址

结果面板会把每一个中间值都列出来,因为本页存在的意义就是让每一步都看得见,而不是藏在黑盒里。

1. 「P2PKH」到底是什么意思

比特币的一笔输出不是一个带余额的账户,而是一个金额加一小段程序,这段程序叫锁定脚本 (scriptPubKey)。要花掉它,下一笔交易必须提供一个解锁脚本(或 witness),让这段 程序执行完在栈上留下一个 TRUE。P2PKH 是 pay to public key hash (支付给公钥哈希)的缩写,它的锁定脚本是:

OP_DUP  OP_HASH160  <20 字节公钥哈希>  OP_EQUALVERIFY  OP_CHECKSIG

顺序很关键:脚本先对花费者提供的公钥重新求哈希,与脚本里承诺的哈希比对,只有比对通过才去验证签名。 「先哈希」正是地址能够这么短、并且公钥在币移动之前不必上链的原因。

那种 Unix 风格的简写 <公钥哈希> OP_CHECKSIG 描述的是更早的 P2PK (pay to public key,直接支付给公钥)形式:它的锁定脚本里压入的是整把公钥,而不是公钥的哈希。中本聪最早的交易 用的就是它,代价是输出更大:

P2PK(2009 年遗留形式)P2PKH(本页)
锁定脚本<公钥> OP_CHECKSIGOP_DUP OP_HASH160 <hash160> OP_EQUALVERIFY OP_CHECKSIG
scriptPubKey 大小35 字节(压缩)/67 字节(非压缩)25 字节
花费前公钥是否已在链上是 —— 从第一天就公开否 —— 只有花费时才暴露
今天的使用情况罕见,主要是 2009–2010 年从未动过的币此后十年单密钥钱包的默认格式

脚本执行的每一步

花费者的解锁脚本是 <签名> <公钥>。下面用演示私钥的真实取值,逐步展示解释器的动作:

#操作执行后的栈
1从 scriptSig 压入签名[sig]
2从 scriptSig 压入压缩公钥[sig, 02ff812e…ee80]
3OP_DUP —— 复制栈顶[sig, 公钥, 公钥]
4OP_HASH160 —— 对副本求哈希[sig, 公钥, 21f57b6d…9012]
5压入脚本中承诺的哈希[sig, 公钥, 21f57b6d…9012, 21f57b6d…9012]
6OP_EQUALVERIFY —— 比较、弹出两者,不等则立即失败[sig, 公钥]
7OP_CHECKSIG —— 用公钥验证签名[TRUE]

可见哈希不是「顺手做的优化」,它就是身份校验本身。若花费者给出的公钥哈希不匹配, OP_EQUALVERIFY 会直接失败,根本轮不到签名运算。

2. 逐字节看构造过程

Base58Check 的输入恰好是 25 字节,此外什么都没有 —— 没有 chain code、没有密钥序号、更没有私钥的什么 校验值:

偏移长度字段演示取值
01 字节版本字节 0x00 = 主网 P2PKH00
1 – 2020 字节hash160 = RIPEMD160(SHA256(压缩公钥))21f57b6debcfc5b67182dfb4af1641f0a8189012
21 – 244 字节校验和 = SHA256(SHA256(第 0–20 字节)) 的前 4 字节cbd7667e
—共 25 字节200 位,这就是一个 1… 地址的全部内容0021f57b…9012cbd7667e

25 字节 = 200 位。由于 Base58 每个字符携带 log₂(58) ≈ 5.858 位信息,编码后的长度是 33 或 34 个字符 (200 / 5.858 ≈ 34.1)。演示地址正好 34 个字符。

为什么地址一定以「1」开头

Base58 本质上是「以 58 为进制的整数转换」,而纯粹的整数转换会把前导零字节抹掉。于是编码规则里额外加了 一条:输入中每一个前导的 0x00 字节,在输出开头对应一个字面字符 1。主网 P2PKH 的版本字节正好就是 0x00,所以第一个字符永远是 1。改掉版本字节,首字符随之改变 —— 这一个字节就是 1…、3…、 m… 长得不一样的全部原因。

「以 1 开头」只是线索,不是证明

合法的主网 P2PKH 地址必定以 1 开头,但反过来不成立:解码器必须同时检查版本字节、载荷长度 以及校验和。永远不要把前缀当作校验 —— 下面那个演示测试网地址之所以以 m 开头,正是 这个道理。

3. 为什么是 hash160 = RIPEMD160(SHA256(x))

两个不同的哈希函数串联使用,理由是纵深防御。仅攻破 SHA-256 的碰撞性对攻击者 毫无用处,因为 32 字节摘要还要喂给第二个结构完全不同的函数:想造出两把 hash160 相同的公钥, 必须在复合函数上找到碰撞,也就是两个设计都得破。同时,哈希两次也把结果压缩到 20 字节,让每个地址、 脚本和输出都更小。

函数输出生日碰撞界原像界在本页中的作用
SHA-25632 字节 / 256 位约 2128约 2256对公钥做全强度承诺
RIPEMD-16020 字节 / 160 位约 280约 2160把承诺值变短
hash160 = RIPEMD160∘SHA25620 字节 / 160 位约 280约 2160地址承诺的就是它

针对某个具体地址的现实威胁是「第二原像」,而不是随便找一个碰撞:攻击者必须找到一把公钥,它的 哈希等于你那 160 位的值,代价约 2160。280 的碰撞界只影响攻击者自己挑选的两把 密钥,因此用 20 字节换取更小的脚本被认为是划算的取舍 —— 而且直到今天它依然没有被攻破。

4. 那 4 个字节的校验和究竟防住了什么

校验和是 SHA256(SHA256(payload))[0..3],即 32 位,编码前附在载荷后面。它的全部职责是捕获 无意的抄写错误:抄错一个字符后解码出的整数就变了,而随机损坏仍然能碰巧匹配这 32 位的概率是 2-32 ≈ 1 / 42.9 亿。这就是为什么地址少抄一个字符时,几乎所有钱包都会大声报错。

校验和不是签名

校验和没有密钥、算法公开:任何人都能为自己想要的载荷算出一个正确的校验和 —— 包括一个把钱付给 他自己的载荷。它防的是笔误和截断,防不了在邮件、剪贴板或被人动手脚的网页里被替换掉的地址。 请在持有私钥的设备上核对地址的头尾若干字符。

5. 主网 vs 测试网:一个字节决定一切

对同一个 hash160,主网地址与测试网地址的唯一区别就是版本字节。同样的 20 字节,不同的首字节,完全不同的 字符串:

网络P2PKH 版本P2PKH 前缀P2SH 版本P2SH 前缀WIF 版本Bech32 前缀
主网0x001…0x053…0x80bc1
测试网 / signet / regtest*0x6Fm… / n…0xC42…0xEFtb1

* 这几个测试网络共用上表里的 Base58 版本字节,只有 bech32 的可读部分不同(regtest 为 bcrt1)。对演示私钥的 hash160,主网地址是 146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT,测试网地址是 micWfnN6LUy38jVRPD2Mw7YMa873zjixGw —— 同一个 20 字节承诺,指向两条不同的链。

测试网地址收不到主网的币

两个字符串解码出的 hash160 相同,但版本字节是收款链上输出脚本的一部分。把主网的币付给一个 tb1… 或 m… 地址,等于在一条链上向「你在另一条链上掌握私钥」的地址转账 —— 在主网上这些币直接丢失。这类复制粘贴错误不可撤销,没有任何客服可以找。

6. 用演示私钥做的实例演算

下面就是本页对 0824c314…171ca 实际算出的全部值,结果面板会实时重算它们:

步骤取值
私钥 k0824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171ca
压缩公钥(33 字节)02ff812e26116a9aa140abe629e7f8a38401653caf925119def59ed3758c67ee80
它的 SHA-256(32 字节)067eb00a0b9864633b020eef374476142daba913c5481ad6a4741cc8ab702617
hash160 = 其 RIPEMD-160(20 字节)21f57b6debcfc5b67182dfb4af1641f0a8189012
载荷 = 00 ‖ hash160(21 字节)0021f57b6debcfc5b67182dfb4af1641f0a8189012
校验和(4 字节)cbd7667e
被编码的 25 字节0021f57b6debcfc5b67182dfb4af1641f0a8189012cbd7667e
P2PKH 地址146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT(34 字符)
对应的 scriptPubKey(25 字节)76a91421f57b6debcfc5b67182dfb4af1641f0a818901288ac

读这段脚本:76 = OP_DUP,a9 = OP_HASH160, 14 = 「接下来压入 20 字节」,随后是哈希本身,88 = OP_EQUALVERIFY, ac = OP_CHECKSIG。五个操作码加一个常量 —— 25 个字节定义了谁有权花这笔钱。

7. 为什么地址不是公钥

哈希带来的一个隐性安全收益

因为公钥在币移动之前一直隐藏,一个从未花费过的 P2PKH 地址同时受到两个独立难题的保护:哈希原像 (2160),以及后来看到公钥的人面临的那道椭圆曲线离散对数题。已经花费过的地址则把 公钥永久暴露,第一层保护随之消失 —— 在考虑未来的量子攻击者时,这是个必须纳入考量的区别。

8. 地址复用是隐私问题,不是共识问题

区块链是公开且永久保存的账本,所以地址不是一个能躲在其后的账户,而是一个永久标签。向同一地址的每一笔 付款,连同金额与时间,都会被任何人关联起来。有两个后果值得强调:

标准解法是分层确定性钱包(BIP32/BIP44):从同一个种子为每一笔收款派生新地址,找零也发往新地址。 复用地址既不多花手续费,在链上也完全合法 —— 这正是大量软件依然这么干的原因。

9. 这一步在推导链上的位置

10. 安全须知

永远不要把真实私钥粘进你无法掌控的页面

本工具的一切计算都在提供它的服务器的 PHP 里完成,不写日志、不外发 —— 但这条保证的上限就是运营者本身。 任何在日志、代理、截图或浏览器历史里瞥见你私钥的人,都能花掉由它派生出的所有地址上的全部币。真要管钱, 请用你自己构建、离线运行的软件,或者硬件钱包。

11. 常见错误

12. 速查表

项目取值
公式Base58Check(0x00 ‖ hash160(压缩公钥))
哈希输入33 字节压缩公钥(66 位十六进制)
哈希函数hash160 = RIPEMD160(SHA256(x)),20 字节
版本字节主网 0x00,测试网 0x6F
被编码的载荷25 字节 = 1 版本 + 20 哈希 + 4 校验和
校验和SHA256(SHA256(payload)) 的前 4 字节,32 位
地址长度33 或 34 个 Base58 字符
锁定脚本大小25 字节
演示地址146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT
可逆吗不可逆 —— 单向哈希承诺