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

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

摘自《精通比特币》

在区块链的世界里,我们持有的比特币只是一串私钥,一串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的十六进制表示。

3.243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8

所以保证比特币安全的一条重要原则就是:一定要用真随机数作为私钥。

在Bitcoin Core等钱包里,随机数生成算法已经非常专业,重合的概率为0,可以放心使用。

如何将私钥导入钱包?

256位的数字不能直接在Bitcoin Core钱包里使用,需要转换为WIF格式,需要用到下面的命令。

bx ec-to-wif -u 3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8

返回的结果:

5JCRYcJrKGLTK6R3PbHopfY9BRdmtrq5TCTesx7x9mQUDeYDfZj

在Bitcoin Core时运行importprivkey命令就可以导入指定的私钥,查看余额了。

--- END ---

原文发布于微信公众号 - 申龙斌的程序人生(slbGTD)

原文发表时间:2018-03-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据结构与算法

BZOJ4006: [JLOI2015]管道连接(斯坦纳树,状压DP)

1941
来自专栏PPV课数据科学社区

【学习】使用hadoop进行大规模数据的全局排序

1. Hellow hadoop~~! Hadoop(某人儿子的一只虚拟大象的名字)是一个复杂到极致,又简单到极致的东西。 说它复杂,是因为一个hadoop...

3033
来自专栏数据结构与算法

1010 过河卒

1010 过河卒 2002年NOIP全国联赛普及组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解  查看运行结果...

2865
来自专栏用户画像

2.1.3 编码与调制

数据无论是数字的还是模拟的,为了传输的目的都必须转变成信号,把数据变换为模拟信号的过程称为调制,把数据变换为数字信号的过程称为编码。

761
来自专栏CSDN技术头条

使用hadoop进行大规模数据的全局排序

1. Hellow hadoop~~! Hadoop(某人儿子的一只虚拟大象的名字)是一个复杂到极致,又简单到极致的东西。 说它复杂,是因为一个hadoop...

3475
来自专栏机器之心

教程 | 如何在Julia编程中实现GPU加速

为了简化操作,可以在 nextjournal 上注册账户,点击「edit」即可直接运行文章中的简单代码了。

1982
来自专栏人工智能LeadAI

拼图游戏和它的AI算法

写了个拼图游戏,探讨一下相关的AI算法。拼图游戏的复原问题也叫做N数码问题。 拼图游戏 N数码问题 广度优先搜索 双向广度优先搜索 A*搜索 游戏设定 实现一个...

59311
来自专栏PPV课数据科学社区

用python对汽车油耗进行数据分析

- 从http://fueleconomy.gov/geg/epadata/vehicles.csv.zip 下载汽车油耗数据集并解压 - 进入jupyte...

4778
来自专栏深度学习之tensorflow实战篇

python jieba分词(结巴分词)、提取词,加载词,修改词频,定义词库

“结巴”中文分词:做最好的 Python 中文分词组件,分词模块jieba,它是python比较好用的分词模块, 支持中文简体,繁体分词,还支持自定义词库。 ...

5K7
来自专栏Spark学习技巧

干货:基于Spark Mllib的SparkNLP库。

引言 这是来自John Snow Labs工程团队的社区博客和工作,解释了他们对开源Apache Spark自然语言处理(NLP)库的贡献。 Apache Sp...

2748

扫码关注云+社区

领取腾讯云代金券