die Idee schwirrte mir schon eine weile im Kopf, ob das sinnvoll ist. Ich habe es mal einfach implementiert.
Und zwar hashing verbunden mit einem etwas anderes Proof of Work. Vor dem Hashing wird aus einer großen Datei einen für das zu hashende Element zuordenbares Teil als Salt benutzt. Wenn man also hashen will, braucht man entweder diese 34 Terabyte Lokal, was ärgerlich sein kann oder man muss für jedes hashen einen HTTP request machen, was langsamer ist.
Warum habe ich das jetzt mit den Chunks gemacht? egal, die Idee Zählt.
Macht doch Sinn, oder?



Code: Alles auswählen
import hashlib
import struct
import requests
JUNK = 'http://darksky.slac.stanford.edu/simulations/ds14_a/ds14_a_1.0000'
JUNK_HTTP_CONTENT_LENGTH = 34359739943392 # that is 34 terabytes
CHUNK_SIZE = 64
HASH = 'ripemd160'
chunks_count = int(JUNK_HTTP_CONTENT_LENGTH/CHUNK_SIZE)
def get_junk_chunk(index):
if index > chunks_count:
raise ValueError('should not exceed {}'.format(chunks_count))
start = index * CHUNK_SIZE
end = start + CHUNK_SIZE - 1
resp = requests.get(
JUNK,
headers={'range': 'bytes={}-{}'.format(start, end)})
resp.raise_for_status()
return resp.content
def get_salt(hashable):
h = hashlib.new(HASH)
h.update(hashable)
bytes = h.digest()[:8]
hash_int = struct.unpack('Q', bytes)[0]
max_hash_int = 2**64-1
hash_percent = hash_int/float(max_hash_int)
index = round(hash_percent * chunks_count)
return get_junk_chunk(index)
def hash(hashable):
h = hashlib.new(HASH)
h.update(hashable + get_salt(hashable))
return h.hexdigest()
if __name__ == '__main__':
print(hash('hello world'.encode())) # fbc9e2bbaf17488e28862475694d6da3c46fa073
print(hash('hash this'.encode())) # 869480ba313ec481b5487860bf4e6ff7ef0eae1c
print(hash('foo bar baz'.encode())) # d4a728c9681d878c85a0cdfb710134e7c60bef2d