Python3 Crypto.Hash - дайджест SHA всегда начинается с двоичного 1 - PullRequest
2 голосов
/ 18 марта 2019

Я работаю над проектом, в котором я пытаюсь создать очень простую криптовалюту на основе блокчейна. Это упрощенная версия способа, которым я пытаюсь хэшировать блочный объект (очевидно, поля класса 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, что мешает всей идее сложности майнинга и проверки работоспособности. Более важно, однако, что это не ожидаемое поведение хеш-функции. Что мне не хватает?

1 Ответ

1 голос
/ 18 марта 2019

Python по умолчанию не дополняет нулю перед двоичными числами, поэтому первая цифра любого двоичного числа будет равна единице.

>>> 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
...