Block头部解析

2023-11-12

Block解析介绍了Block的各个组成部分:魔法数、块大小、块头部、交易个数、交易,本文将详细介绍块魔法数和块头部的各个组成部分。


魔法数

魔法数是比特币客户端解析Block数据时的识别码,比特币正式网络的魔法数是0xD9B4BEF9。不同的币种的魔法数一般不同,比如打开莱特币的.dat文件我们可以发现莱特币的魔法数是0xDCB7C1FC。


版本号

目前比特币网络块链上的块的版本号有两个:1和2,两者的区别在于版本2块中的Coinbase交易加入了块高度,我们来看高度为227836和227835两个块中的Coinbase交易数据。


两个版本的Coinbase交易数据在结构上并没有区别,版本2在输入脚本上添加了4个字节的高度数据,其中第1个字节的值是指后面描述块高度的字节数,比如块227836的Coinbase交易输入脚本

03表示后面3个字节描述块高度,fc7903是小端顺序,所以实际的值是0x0379fc,转换为十进制值是227836。


为什么版本2要在Coinbase交易的输入脚本里面要加块高度呢?原因至少有两个:

1.能进一步保证接下来的每个块的哈希都是唯一的。由于在Coinbase交易里面加入了块高度,所以块头部的Merkle树根哈希一定是唯一的,所以该Block的块头部哈希一定唯一,所以接下来的块的上一个块头部哈希是唯一的,所以接下来的块头部哈希唯一。

2.能更好的了解那些孤立块形成的原因。比如可能是由于块高度冲突造成的。

上一个块哈希依然以块227836和227835为例,块227835的哈希值是

00000000000001aa077d7aa84c532a4d69bdbff519609d1da0835261b7a74eb6 块227836的块头部数据是

其中标红的是上一个块哈希,由于是小端序列所以实际值跟块227835的块哈希相同。

创世块没有上一个块,所以上一个块哈希是0。

Merkle树根哈希

Merkle树是哈希的二叉树,在比特币中使用两次SHA-256算法来生成Merkle树,如果叶子个数为奇数,则要重复计算最后一个叶子的两次SHA-256傎,以达到偶数叶子节点的要求:

计算过程:首先按照交易顺序将交易id放在最底层;第二层的每个元素是相连续的两个HASH值的两次HASH值;重复这个过程,直到某一层只有一个HASH值,这就是Merkle根。

下面以块100000演示计算过程:

第一步:使用比特币客户端获取块100000的数据。

getblock 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506

{

"hash" : "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",

"confirmations" : 211828,

"size" : 957,

"height" : 100000,

"version" : 1,

"merkleroot" : "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766",

"tx" : [

"8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87",

"fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4",

"6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4",

"e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d"

],

"time" : 1293623863,

"nonce" : 274148111,

"bits" : "1b04864c",

"difficulty" : 14484.16236123,

"chainwork" : "0000000000000000000000000000000000000000000000000644cb7f5234089e",

"previousblockhash" : "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250",

"nextblockhash" : "00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090"

}

第二步:将txid转换为小端序列,得到最下层的Merkle树叶节点。

[

"876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148c",

"c40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff",

"c46e239ab7d28e2c019b6d66ad8fae98a56ef1f21aeecb94d1b1718186f05963",

"1d0cb83721529a062d9675b98d6e5c587e4a770fc84ed00abc5a5de04568a6e9"

]

第三步:将第1,2两个txid,3,4两个txid连接起来进行双重哈希,需要注意的是并不是用它们的字符串形式而是要用对应的16进制编码,最后得到第二层的Merkle树节点。

[

"15b88c5107195bf09eb9da89b83d95b3d070079a3c5c5d3d17d0dcd873fbdacc",

"49aef42d78e3e9999c9e6ec9e1dddd6cb880bf3b076a03be1318ca789089308e",

]

第四步:重复第三步的操作,得到第三层的Merkle树节点

[

"6657a9252aacd5c0b2940996ecff952228c3067cc38d4885efb5a4ac4247e9f3"

]

由于只剩下一个,所以这就是最终的Merkle数根节点。

第五步:将根节点转换成大端序列,得到

"f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766"

Github上有一个python程序描述了这个计算过程,可参考如下链接:

https://gist.github.com/shirriff/c9fb5d98e6da79d9a772#file-merkle-py


为什么要构建这样一颗Merkle树并保存根节点的哈希值到块头部呢?原因至少有如下几点:

1.在不存储块中完整交易信息的情况保证块哈希的唯一性。由于块哈希是对整个块进行哈希,因此只要其中的代表交易的信息是唯一的,那么块哈希就是唯一的,所以如果不存储交易信息而使用Merkle根部哈希参与到块哈希中就能大大减小数据量的存储。

2.在不存储块中完整交易信息的情况下验证块中的交易。假如节点要验证块100000中的第1笔交易数据是否正确,它可以从别的节点那里获取第1,2两笔交易,以及第3,4两笔交易的Merkle树上层节点值,而无需从对方那里下载完整的交易数据。

时间戳

时间戳是块被创造出来时加上的一个Unix时间,这个时间必须之前的11个块时间的中间值要大,并且要比当前网络校准时间小2小时。当前网络校准时间是指与你的节点相连的其它节点时间的中间值。

当一个节点连接另外一个节点时,它会收到对方的Unix时间并保存与本地时间的偏差,最终的网络校准时间就是所有偏差的中间值加上本地时间,不过比特币协议规定偏差最大就是70分钟。

需要注意的是,比特币的时间戳系统并非单调递增的,比如块139793的时间戳是1312599459,而块139792的时间戳是1312599808比139793的要大。

目标值

前文简要介绍了下根据块数据得到目标值的计算方式,那么目标值到底是怎么设置的呢?在此之前我先介绍下怎样把一个正整数转换成目标值的那种结构(以下简称目标值结构)。

第一步:将正整数转换成base256,得到base256的个数。

第二步:如果base256中的第1个字节大于127(0x7f),则在头部插入00。

第三步:截取base256的前3个字节,不足3个的在尾部补00。

第四步:将第一步得到的base256个数放在最前面。

例一:将1000转换成目标值结构

第一步:1000 = 03 e8,base256的个数是2个。

第二步:03比7f小,所以头部不插入一个00,依然是03 e8。

第三步:截取不足3个,所以尾部补00得到03 e8 00。

第四步:将02放在最前面,最终得到02 03 e8 00。

例二:将2^(256-32)-1转换成目标值结构

2^(256-32)-1= ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

一共28个ff

由于ff>7f,所以在前面插入00,得到

00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

截取3个,再加上base256的个数,得到

1d 00 ff ff

目标值的设定通过比特币源代码可以获得计算方式

首先,初始的目标值就是网络设定的1d 00 ff ff

其次,一个周期(两周, 2016个块)内下一个块的难度值保持不变。

最后,新的周期的难度值根据上个周期产出2016个块的实际时间进行调整。

难度

说完目标值,顺带说下难度。难度用于描述在给定的目标值下寻找合适的哈希值的困难程度,难度并不存储在块数据中,它是根据一个公式计算出来的。

难度 = 最大目标值/当前目标值

最大目标值有不同的取值方式,比特币客户端一般取初始目标值

0xFFFF0000000000000000000000000000000000000000000000000000

以块311931为例,它的目标值是406809574转换成目标值结构是183F6BE6,因此

难度=0xFFFF0000000000000000000000000000000000000000000000000000/

0x3F6BE6000000000000000000000000000000000000000000

=17336316978.51

随机数

在介绍随机数前先介绍下块哈希是怎么来的,比如块125552的哈希是00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d

这个值并没有存储在块数据中,它是根据块头部进行双重哈希得来的,算法如下:

第一步:将块版本,上一个块哈希,Merkle根哈希,时间戳,目标值,随机数连接起来。

第二步:将连接数进行双重哈希,得到的结果就是块的哈希。

可参考如下Python代码:


Block解析介绍了Block的各个组成部分:魔法数、块大小、块头部、交易个数、交易,本文将详细介绍块魔法数和块头部的各个组成部分。


魔法数

魔法数是比特币客户端解析Block数据时的识别码,比特币正式网络的魔法数是0xD9B4BEF9。不同的币种的魔法数一般不同,比如打开莱特币的.dat文件我们可以发现莱特币的魔法数是0xDCB7C1FC。


版本号

目前比特币网络块链上的块的版本号有两个:1和2,两者的区别在于版本2块中的Coinbase交易加入了块高度,我们来看高度为227836和227835两个块中的Coinbase交易数据。


两个版本的Coinbase交易数据在结构上并没有区别,版本2在输入脚本上添加了4个字节的高度数据,其中第1个字节的值是指后面描述块高度的字节数,比如块227836的Coinbase交易输入脚本

03表示后面3个字节描述块高度,fc7903是小端顺序,所以实际的值是0x0379fc,转换为十进制值是227836。


为什么版本2要在Coinbase交易的输入脚本里面要加块高度呢?原因至少有两个:

1.能进一步保证接下来的每个块的哈希都是唯一的。由于在Coinbase交易里面加入了块高度,所以块头部的Merkle树根哈希一定是唯一的,所以该Block的块头部哈希一定唯一,所以接下来的块的上一个块头部哈希是唯一的,所以接下来的块头部哈希唯一。

2.能更好的了解那些孤立块形成的原因。比如可能是由于块高度冲突造成的。

上一个块哈希依然以块227836和227835为例,块227835的哈希值是

00000000000001aa077d7aa84c532a4d69bdbff519609d1da0835261b7a74eb6 块227836的块头部数据是

其中标红的是上一个块哈希,由于是小端序列所以实际值跟块227835的块哈希相同。

创世块没有上一个块,所以上一个块哈希是0。

Merkle树根哈希

Merkle树是哈希的二叉树,在比特币中使用两次SHA-256算法来生成Merkle树,如果叶子个数为奇数,则要重复计算最后一个叶子的两次SHA-256傎,以达到偶数叶子节点的要求:

计算过程:首先按照交易顺序将交易id放在最底层;第二层的每个元素是相连续的两个HASH值的两次HASH值;重复这个过程,直到某一层只有一个HASH值,这就是Merkle根。

下面以块100000演示计算过程:

第一步:使用比特币客户端获取块100000的数据。

getblock 000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506

{

"hash" : "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",

"confirmations" : 211828,

"size" : 957,

"height" : 100000,

"version" : 1,

"merkleroot" : "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766",

"tx" : [

"8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87",

"fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4",

"6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4",

"e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d"

],

"time" : 1293623863,

"nonce" : 274148111,

"bits" : "1b04864c",

"difficulty" : 14484.16236123,

"chainwork" : "0000000000000000000000000000000000000000000000000644cb7f5234089e",

"previousblockhash" : "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250",

"nextblockhash" : "00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090"

}

第二步:将txid转换为小端序列,得到最下层的Merkle树叶节点。

[

"876dd0a3ef4a2816ffd1c12ab649825a958b0ff3bb3d6f3e1250f13ddbf0148c",

"c40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff",

"c46e239ab7d28e2c019b6d66ad8fae98a56ef1f21aeecb94d1b1718186f05963",

"1d0cb83721529a062d9675b98d6e5c587e4a770fc84ed00abc5a5de04568a6e9"

]

第三步:将第1,2两个txid,3,4两个txid连接起来进行双重哈希,需要注意的是并不是用它们的字符串形式而是要用对应的16进制编码,最后得到第二层的Merkle树节点。

[

"15b88c5107195bf09eb9da89b83d95b3d070079a3c5c5d3d17d0dcd873fbdacc",

"49aef42d78e3e9999c9e6ec9e1dddd6cb880bf3b076a03be1318ca789089308e",

]

第四步:重复第三步的操作,得到第三层的Merkle树节点

[

"6657a9252aacd5c0b2940996ecff952228c3067cc38d4885efb5a4ac4247e9f3"

]

由于只剩下一个,所以这就是最终的Merkle数根节点。

第五步:将根节点转换成大端序列,得到

"f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766"

Github上有一个python程序描述了这个计算过程,可参考如下链接:

https://gist.github.com/shirriff/c9fb5d98e6da79d9a772#file-merkle-py


为什么要构建这样一颗Merkle树并保存根节点的哈希值到块头部呢?原因至少有如下几点:

1.在不存储块中完整交易信息的情况保证块哈希的唯一性。由于块哈希是对整个块进行哈希,因此只要其中的代表交易的信息是唯一的,那么块哈希就是唯一的,所以如果不存储交易信息而使用Merkle根部哈希参与到块哈希中就能大大减小数据量的存储。

2.在不存储块中完整交易信息的情况下验证块中的交易。假如节点要验证块100000中的第1笔交易数据是否正确,它可以从别的节点那里获取第1,2两笔交易,以及第3,4两笔交易的Merkle树上层节点值,而无需从对方那里下载完整的交易数据。

时间戳

时间戳是块被创造出来时加上的一个Unix时间,这个时间必须之前的11个块时间的中间值要大,并且要比当前网络校准时间小2小时。当前网络校准时间是指与你的节点相连的其它节点时间的中间值。

当一个节点连接另外一个节点时,它会收到对方的Unix时间并保存与本地时间的偏差,最终的网络校准时间就是所有偏差的中间值加上本地时间,不过比特币协议规定偏差最大就是70分钟。

需要注意的是,比特币的时间戳系统并非单调递增的,比如块139793的时间戳是1312599459,而块139792的时间戳是1312599808比139793的要大。

目标值

前文简要介绍了下根据块数据得到目标值的计算方式,那么目标值到底是怎么设置的呢?在此之前我先介绍下怎样把一个正整数转换成目标值的那种结构(以下简称目标值结构)。

第一步:将正整数转换成base256,得到base256的个数。

第二步:如果base256中的第1个字节大于127(0x7f),则在头部插入00。

第三步:截取base256的前3个字节,不足3个的在尾部补00。

第四步:将第一步得到的base256个数放在最前面。

例一:将1000转换成目标值结构

第一步:1000 = 03 e8,base256的个数是2个。

第二步:03比7f小,所以头部不插入一个00,依然是03 e8。

第三步:截取不足3个,所以尾部补00得到03 e8 00。

第四步:将02放在最前面,最终得到02 03 e8 00。

例二:将2^(256-32)-1转换成目标值结构

2^(256-32)-1= ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

一共28个ff

由于ff>7f,所以在前面插入00,得到

00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

截取3个,再加上base256的个数,得到

1d 00 ff ff

目标值的设定通过比特币源代码可以获得计算方式

首先,初始的目标值就是网络设定的1d 00 ff ff

其次,一个周期(两周, 2016个块)内下一个块的难度值保持不变。

最后,新的周期的难度值根据上个周期产出2016个块的实际时间进行调整。

难度

说完目标值,顺带说下难度。难度用于描述在给定的目标值下寻找合适的哈希值的困难程度,难度并不存储在块数据中,它是根据一个公式计算出来的。

难度 = 最大目标值/当前目标值

最大目标值有不同的取值方式,比特币客户端一般取初始目标值

0xFFFF0000000000000000000000000000000000000000000000000000

以块311931为例,它的目标值是406809574转换成目标值结构是183F6BE6,因此

难度=0xFFFF0000000000000000000000000000000000000000000000000000/

0x3F6BE6000000000000000000000000000000000000000000

=17336316978.51

随机数

在介绍随机数前先介绍下块哈希是怎么来的,比如块125552的哈希是00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d

这个值并没有存储在块数据中,它是根据块头部进行双重哈希得来的,算法如下:

第一步:将块版本,上一个块哈希,Merkle根哈希,时间戳,目标值,随机数连接起来。

第二步:将连接数进行双重哈希,得到的结果就是块的哈希。

可参考如下Python代码:


由于块头部的其它字段都是固定的,但生成一个不超过目标值的块哈希并非一次就能成功的事情,所以需要一个随机数不停的变化去尝试去生成块哈希直到符合要求。

参考

http://bitcoin.stackexchange.com/questions/2924/how-to-calculate-new-bits-value

http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html

https://en.bitcoin.it/wiki/Category:Technical

参考

http://bitcoin.stackexchange.com/questions/2924/how-to-calculate-new-bits-value

http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html

https://en.bitcoin.it/wiki/Category:Technical

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Block头部解析 的相关文章

  • 从 UUID 或 HMAC/JWT/哈希生成一次性安全令牌?

    我正在为网络应用程序构建后端 当新用户访问该网站并单击Sign Up按钮 他们将填写一个超级简单的表格 要求他们提供用户名 密码 然后他们就会提交 这会提示服务器向该电子邮件地址发送一封验证电子邮件 然后 他们将检查电子邮件 单击链接 验证
  • 解码 Torrent 追踪器抓取的 Torrent 哈希值?

    我在用BEncoded PHP 库 http proger i forge net BEncoded E2 80 93 handling torrent files in PHP 7Tn解码来自 Bittorrent 跟踪器的编码响应 Tr
  • 可以将用户的盐与密码哈希保存在同一个表中吗?

    是不是还好而且没啥用 它可以保存在另一个表甚至另一个数据库中 你怎么认为 附 为了更高的安全性 我也有常量的盐 花生 它是保存在配置文件 而不是数据库 中的常量值 因此 如果黑客想要以某种方式破解密码 他还需要访问文件服务器和数据库 是的
  • DJB 哈希函数中数字 5381 的原因是什么?

    谁能告诉我为什么 DJB 哈希函数中使用数字 5381 DJB 哈希函数定义为 h 0 5381 h i 33h i 1 s i 这是一个 C 实现 unsigned int DJBHash char str unsigned int le
  • 使用随机盐改进密码散列

    我正在创建一个网站 并尝试决定如何加密用户密码以将其存储在 SQL 数据库中 我意识到使用简单的 md5 密码 是非常不安全的 我正在考虑使用 sha512 password salt 并且我一直在研究生成有用盐的最佳方法 我读过很多文章
  • Ruby:在each、map、inject、each_with_index 和each_with_object之间进行选择

    许多年前 当我开始编写 Ruby 时 我花了一段时间才理解each https ruby doc org core 2 2 0 Array html method i each and map https ruby doc org core
  • Perl 中大型哈希表的快速加载

    我有大约 30 个文本文件 其结构如下 wordleft1 wordright1 wordleft2 wordright2 wordleft3 wordright3 文件总大小约1GB 包含约3200万行单词组合 我尝试了几种方法来尽可能快
  • 如何从 PHP 字符串中获取 64 位整数哈希值?

    我需要 64 位字符串整数哈希值来实现哈希映射之类的功能 在我看来 没有可以返回 64 位整数的原生 PHP 哈希功能 我认为可以获取 sha1 哈希值的第一部分并将其转换为整数 然而 这不会带来最好的性能 而且转换似乎很棘手 当然 如果不
  • PHP - 以某种方式哈希对象,具有相同字段值的不同对象具有相同的哈希值

    我正在寻找一种方法来为 PHP 对象生成某种哈希值 通用解决方案 如果可能的话 可以使用所有分类的 内置的和自定义的 SplObjectStorage getHash 不是我正在寻找的 因为它会为给定类的每个实例生成不同的哈希值 为了描述这
  • 如何测试两个哈希值(密码)是否相似?

    当用户创建密码时 我对其进行哈希处理 包括盐 并将其保存在数据库中 现在 当用户想要更改他或她的密码时 我想测试新密码是否与旧密码太相似 我已经在不同的服务上看到过这种情况 尤其是网上银行 所以 我想我会使用similar text or
  • 为什么数组前需要加星号?

    我不知道这是哈希问题还是数组问题 但我不明白为什么第三个示例中需要星号 才能获得填充数据的哈希 如果没有它 它会输出一个空的哈希值 coding utf 8 require pp pp first name Shane last name
  • java中带有二维键的映射

    我想要一个在 Java 中由两个键索引的映射 在其中使用两个键放置和检索值的映射 需要明确的是 我正在寻找以下行为 map put key1 key2 value map get key1 key2 returns value map ge
  • Perl 使用什么哈希函数/算法?

    有人能解释一下 Perl 用于将字符串映射到索引的哈希函数 算法吗 有相关读物吗 这个答案早于 5 28 中进行的哈希函数更改 请参阅 默认哈希函数更改 perldelta 为 5 28 http perldoc perl org perl
  • Oh-my-zsh 哈希(井号)符号错误模式或未找到匹配项

    我很确定是与我的 Oh my zsh 配置相关的东西 但我不知道它是什么 当我在 git 命令中使用 符号时 但也适用于其他所有命令 例如 ls 2 我收到 错误模式 错误或 找不到匹配项 我猜是要计算一些东西 但我找不到在哪里配置它 I
  • 如何使用符号来标识 ruby​​ 方法中的参数

    我正在学习 Rails 并回到 ruby 来了解 Rails 中的方法 以及 ruby 的实际工作原理 当我看到如下方法调用时 validates first name presence gt true 我有点迷惑不解了 如何在 ruby
  • Qt 计算和比较密码哈希

    目前正在 Qt 中为测验程序构建面向 Web 的身份验证服务 据我了解 在数据库中存储用户密码时 必须对其进行隐藏 以防落入坏人之手 流行的方法似乎是添加的过程Salt https en wikipedia org wiki Salt cr
  • 使用javascript向url添加哈希而不滚动页面?

    在不滚动页面的情况下向 url 添加哈希 使用 JavaScript 我打开页面 我向下滚动 我单击添加哈希的链接 可能带有值 test 示例 http www example com test http www example com t
  • 在同步函数中使用 javascript `crypto.subtle`

    在javascript中 是否可以使用浏览器内置的sha256哈希 https developer mozilla org en US docs Web API SubtleCrypto digest Converting a digest
  • 如何使redis中的“HSET”子键“过期”?

    我需要使 Redis 哈希中所有超过 1 个月的密钥过期 这不可能 https github com antirez redis issues 167 issuecomment 2559040 为了保持 Redis 简单 https git
  • 如何将两个不同的哈希数组中的值添加在一起?

    我有两个哈希数组 哈希值的键不同 player scores1 first name gt Bruce score gt 43 time gt 50 first name gt Clark score gt 45 minutes gt 20

随机推荐

  • Redis入门——Key、五大数据类型图文详解

    文章目录 1 Redis简介 2 Redis常见命令 3 Redis Key关键字 4 五大数据类型简介 4 1 String 字符串 4 2 List 列表 4 3 Set 4 3 Hash 4 4 ZSet 1 Redis简介 Redi
  • 什么是索引?MySQL常见的几种索引类型和原理

    来源 素文宅博客 地址 https blog yoodb com yoodb article detail 1536 在关系数据库中 索引是一种单独的 物理的对数据库表中一列或多列的值进行排序的一种存储结构 它是某个表中一列或若干列值的集合
  • Java---JUC并发篇(多线程详细版)

    Java 多线程 1 并发基础 线程篇 1 1 java线程状态及线程状态之间的转化 1 2 操作系统层面有5种状态 2 线程池的核心参数 7个核心参数 3 sleep与wait方法对比 4 lock锁与synchronized锁区别 5
  • docker启动容器及启动一个挂载数据卷的容器

    在docker运行容器前可以先使用docker images列出本地镜像 docker运行容器前需要本地存在对应的镜像 如果本地不存在该镜像 Docker会从镜像仓库下载此镜像 先创建 usr share nginx html 目录 创建数
  • python: more Layer Architecture and its Implementation in Python

    sql server 学生表 DROP TABLE DuStudentList GO create table DuStudentList StudentId INT IDENTITY 1 1 PRIMARY KEY StudentName
  • python操作图像处理

    绘制图形方式一 1 图像读取 img cv imread C Users asus Desktop QQ jpg source cv cvtColor img cv COLOR BGR2RGB 2 均值滤波 blur cv blur img
  • AcWing 99. 激光炸弹(二维前缀和)

    输入样例 2 1 0 0 1 1 1 1 输出样例 1 解析 二维前缀和 枚举每个正方形区间的最大值即可 本题只能开一个5000的二维数组 两个会MLE 代码 include
  • flask+APScheduler定时任务的使用

    APScheduler定时任务使用以及在flask中的调用 APScheduler简介 组成部分 调度器 安装 普通使用安装 结合flask使用安装 使用 添加job add job参数详解 interval 间隔时间 每隔一段时间执行 d
  • Linux下实现编写汇编程序

    本学期的微机原理课程上机使用的是MASM汇编器 上课时使用的是Windows上的DOS 而Linux中的汇编工具是nasm 具体的可以点击链接 http os 51cto com art 201101 243138 htm 这里写代码片 下
  • C++11智能指针的基本原理及使用

    介绍 智能指针是一个类 用来存储指向动态分配对象的指针 负责自动释放动态分配的对象 防止堆内存泄漏 动态分配的资源 交给一个类对象去管理 当类对象声明周期结束时 自动调用析构函数释放资源 分类 auto ptr 已弃用 使用unique p
  • 神经网络算法和遗传算法,数据挖掘神经网络算法

    神经网络算法与进化算是什么关系 应该没有太大的关系吧 我对遗传算法了解一点 遗传算法主要用来优化神经网络第一次运行时所用的连接权值 因为随机的连接权值往往不能对针对的问题有比较好的收敛效果 Matlab神经网络工具箱自动生成的初始权值其实已
  • Tracy 小笔记 Vue - 网络模块封装(axios)

    安装 axios 和 引入 安装 npm install axios save 引用 import axios from axios 网络请求可以测试的几个接口地址 http httpbin org get http 123 207 32
  • Linux中的JDK安装和配置

    Linux中的JDK安装和配置 1 查看是否已安装JDK yum list installed grep java 2 卸载系统Java环境 yum y remove java 1 8 0 openjdk 3 卸载tzdata java y
  • 那年的夏天很笛子

    原文 salance moon spaces live com 在某个阶段 我想应该是时候把至今为止影响自己走上美工 设计 程序之路的历程整理一下了 但是下笔的时候才发现 其实这几乎成了我童年的回忆录 因为程序暂且不算 美工 设计就是我人格
  • Connect函数阻塞

    1 采用select 在学习嵌入式Linux网络编程中 很多同学都发现了一个问题 那就是调用connect函数时 如果服务端关闭 客户 端调用connect 函数时 发现阻塞在那里 而且利用ctrl c信号去停止客户端程序时 需要等待一个较
  • git:一次回滚多个commit

    说明 独立分散的commit共同回滚 git revert n sha 1 git 单次commit对应的sha 1值 sha 1 sha 1 ps n代表不会生成新的commit 如果想直接生成commit请去掉 n 最近连续的coomi
  • hr谈薪资后说请示领导_如何巧妙回答面试中的薪资问题呢?

    好不容易挺过了群面 单面 没想到在HR面被薪资问题打个措手不及 你的期望薪资是多少 说低了总觉得委屈自己 说高了又怕offer不保 好不容易在前面几轮面试积攒的自信 在这个问题上就变成 emm差不多就行吧 然后面试一结束就开始无限后悔 对于
  • 【ML特征工程】第 1 章 :机器学习管道

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • STM32F407 单片机+DMA+环形缓冲区+GPS报文解析

    本文采用DMA 环形缓冲区对GPS报文进行解析 思路是通过DMA中断接收到GPS报文后 存放到环形缓冲区 然后在主程序中解析GPS报文 解析GPS报文的关键是 将环形缓冲区中的字节转换成字符串 然后在字符串中查找GPS报文头标识 例如 GP
  • Block头部解析

    Block解析介绍了Block的各个组成部分 魔法数 块大小 块头部 交易个数 交易 本文将详细介绍块魔法数和块头部的各个组成部分 魔法数 魔法数是比特币客户端解析Block数据时的识别码 比特币正式网络的魔法数是0xD9B4BEF9 不同