专栏名称: 申龙斌的程序人生
分享可繁殖的知识与技能:GTD时间管理、读书心得、个人成长、财富自由之路
目录
相关文章推荐
OSC开源社区  ·  OWL:Manus通用智能体的完全开源复刻、 ... ·  3 天前  
程序员的那些事  ·  刚刚!DeepSeek 杀入全球榜单第 2 ... ·  3 天前  
OSC开源社区  ·  三句话让老板直接给我主动放假 ·  5 天前  
OSC开源社区  ·  听说技术大V们都被"manus"喂饱了,求邀 ... ·  4 天前  
OSC开源社区  ·  LFOSSA女神节福利,激励女性绽放多元力量 ... ·  4 天前  
51好读  ›  专栏  ›  申龙斌的程序人生

我生成的比特币地址竟然与别人的重合了

申龙斌的程序人生  · 公众号  · 程序员  · 2018-03-31 11:00

正文

在《精通比特币》这本书里有一张经典的图,用来说明私钥、公钥和比特币地址三者之间的关系。 私钥可以生成公钥,公钥再生成比特币地址,反过来皆不可行。

摘自《精通比特币》


在区块链的世界里,我们持有的比特币只是一串私钥, 一串256位的二进制数。如果你扔硬币,正面记为0,反面记为1,连扔256次,把它记录下来,再把这串二进制数值转换为十六进制数,你的所有家当就在这串私钥上了。


假设我有这样一串随机数:

3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8


为了让你看清楚它的字节数,我加了一条标尺,256位,64个十六进制数,32个字节。

----.----1----.----2----.----3----.----4----.----5----.----6----
3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8


现在要把这串私钥生成比特币地址。首先准备一个命令行工具小软件Bitcoin Explorer,这款软件可以 运行在Linux,Mac和Windows等操作系统上, 下载的网址:

https://github.com/libbitcoin/libbitcoin-explorer/wiki/Download-BX


软件非常小巧,只有一个文件,我为了方便输入,把文件名改为bx.exe。



私钥生成公钥


打开一个cmd命令行窗口,运行如下命令。


为了方便说明,我把命令和返回结果重新排版:

bx ec-to-public -u 3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8

运行结果如下:
----.----1----.----2----.----3----.----4----.----5----.----6----
04
2e88d239fb78cee0c1c55943a96dcc8b70adf47e18b53f9ba110b6fb871e1f8b
b119f9161df032167181d623a401dde4091c3e0be2001e4dea3e1f53f851aa3a

ec-to-public的 EC是指Elliptic Curve,即椭圆曲线,比特币的加密算法中用到了复杂的椭圆曲线加密,简单来说,就是一串数字,经过加密之后,变换到椭圆曲线上的一个点,这个点有x坐标和y坐标。


返回结果有65个字节。

第一个字节04,表示是 非压缩的公钥格式

紧跟着32个字节,是x坐标。

再跟着32个字节,是y坐标。


椭圆曲线的原理实在太烧脑,我一路研究下去,发现与费马大定理关系紧密,然后入迷般地把《费马大定理》这本书也看完了,万物间存在着巧妙的联系,没想到椭圆曲线又被中本聪应用于比特币的加密算法中。

图片摘自czbaa.com


不管这些原理,我们刚才得到的65个字节的042e88......51aa3a这串数值就是公钥。而从这个公钥出发,反推回私钥是几乎不可能的。



公钥生成地址


原理图如下,摘自《精通比特币》。


这里需要再运行bx sha256、bx ripemd160以及bx address-encode三个命令,最后生成的比特币地址为 17mKugcBDEJbu391Fq41AdwLeGHwJLPRDf


SHA是 Secure Hash Algorithm的缩写,SHA256表示生成的结果为256位的二进制数。经过这一层哈希之后,相当于又做了一次加密。


RIPEMD代表the RACE Integrity Primitives Evaluation Message Digest,256位稍微有点长,用这个算法之后,得到一个长 度为160比特(20字节)的数

本文例子中得到了 4a32d744feaa62eb017674b6a4f5dce397f6b1b9


最后一步加上了校验码和base58编码,防止人工输入错误,这个地址里永远不可能有0(数字0)、O(大写字母o)、l(小写字母L)、I(大写字母i),我们的例子里得到了地址 17mKugcBDEJbu391Fq41AdwLeGHwJLPRDf


完整的命令行:

bx ec-to-public -u 3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8 | bx sha256 | bx ripemd160 | bx address-encode

运行结果:
042e88d239fb78cee0c1c55943a96dcc8b70adf47e18b53f9ba110b6fb871e1f8bb119f9161df032167181d623a401dde4091c3e0be2001e4dea3e1f53f851aa3a
74c743476f536592d64c38d75dfa676fa6d05e5fc5363bde5f7699336c3b6b51
4a32d744feaa62eb017674b6a4f5dce397f6b1b9
17mKugcBDEJbu391Fq41AdwLeGHwJLPRDf

地址重合了?


到blockchain.info里看看这个地址里是否有比特币?访问网址:

https://blockchain.info/address/17mKugcBDEJbu391Fq41AdwLeGHwJLPRDf



这个地址中竟然有4笔历史交易,最近的一笔交易发生于2014年年底,难道是我扔出的256位的随机数中了彩票?


不可能,任意2个人随机生成的地址正好相同的可能性相当于2个人从地球上捡起了同一粒沙子,再把这粒沙子看做地球,相当于2个人又从这个地球里捡起了同一粒沙子。




为什么我生成的比特币地址与别人的地址重合了?因为我的256位随机数并不随机,而是来自于圆周率π = 3.1415926535897932384626的十六进制表示。







请到「今天看啥」查看全文