我正在一个项目中尝试创建一个非常简单的基于区块链的加密货币。这是我尝试对块对象进行哈希处理的方式的简化版本(显然Block
类的字段要复杂得多,但这是主要思想):
from Crypto.Hash import SHA
import json
from collections import OrderedDict
from random import random
class Block(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def to_dict(self):
d = OrderedDict({
'x' : self.x,
'y' : self.y,
'z' : self.z
})
return d
def json(self):
return json.dumps(self.to_dict())
def hash(self):
return SHA.new(self.json().encode('utf8')).hexdigest()
# driver code to test hashing
while True:
x, y, z = [random() for _ in range(3)]
b = Block(x, y, z)
if not bin(int(b.hash(), 16)).startswith('0b1'):
break
上面的驱动程序永远循环。问题是(无论字段的数量和/或值如何)哈希始终以0b1
开头,这与挖掘难度和工作量证明的整个思想相混淆。但是,更重要的是,这不是哈希函数的预期行为。我想念什么?
答案 0 :(得分:1)
默认情况下,Python不会对二进制数的开头进行零填充,因此 any 二进制数的第一位将是一个。
>>> bin(1)
'0b1'
>>> bin(2)
'0b10'
>>> bin(3)
'0b11'
>>> bin(8)
'0b1000'
如果要使用二进制字符串进行修复,请使用字符串格式
>>> "{:04b}".format(1)
'0001'
>>> "{:04b}".format(2)
'0010'
>>> "{:04b}".format(8)
'1000'
>>> "{:04b}".format(15)
'1111'
否则,只需使用二进制和(&
)来检查特定位是否已设置。
>>> bool(1 & 0b1000)
False
>>> bool(3 & 0b1000)
False
>>> bool(8 & 0b1000)
True
>>> bool(15 & 0b1000)
True