2014-11-12 3 views
-1

Я хочу, чтобы хеш-функция была быстрой, устойчивой к столкновению и могла давать уникальный результат. Основное требование - оно должно быть устойчивым. I. Это прогресс (прогресс хеширования) может быть сохранен в файле, а затем возобновлен. Вы также можете предоставить свою собственную реализацию Python.Есть ли какая-либо функция хеша, которая имеет следующие свойства

Реализации на «других языках» также принимаются, если это возможно использовать с Python, не получая грязных внутренних рук.

Заранее спасибо :)

+0

Что вы имеете в виду именно с "уникальным" и "столкновение резистентной"? –

+0

@ErwinSmout Дорогой друг, вопрос обновлен. Теперь вы можете отменить свою Downvote. –

+0

Вероятно, вы получили нисходящий ответ на этот вопрос, потому что SO не является службой написания кода и потому, что вы не отправили какой-либо собственный код. –

ответ

2

Из-за pigeonhole principle не хэш-функции может генерировать хэши, которые являются уникальными/противоударными. Хорошая функция хэширования устойчива к столкновениям и затрудняет создание файла, который создает заданный хеш. Разработка хорошей хэш-функции - это передовая тема, и я, конечно, не специалист в этой области. Однако, поскольку мой код основан на sha256, он должен быть довольно устойчивым к столкновению, и, надеюсь, также сложно создать файл, который создает указанный хэш, но я не могу гарантировать никаких гарантий в этом отношении.


Это возобновляемая хэш-функция, основанная на sha256, которая довольно быстро. Требуется около 44 секунд для хэширования 1,4-гигабайтного файла на моем 2 ГГц компьютере с 2 ГБ оперативной памяти.

persistent_hash.py

#! /usr/bin/env python 

''' Use SHA-256 to make a resumable hash function 

    The file is divided into fixed-sized chunks, which are hashed separately. 
    The hash of each chunk is combined into a hash for the whole file. 

    The hashing process may be interrupted by Control-C (SIGINT) or SIGTERM. 
    When a signal is received, hashing continues until the end of the 
    current chunk, then the file position and current hex digest is saved 
    to a file. The name of this file is formed by appending '.hash' to the 
    name of the file being hashed. 

    Just re-run the program to resume hashing. The '.hash' file will be deleted 
    once hashing is completed. 

    Written by PM 2Ring 2014.11.11 
''' 

import sys 
import os 
import hashlib 
import signal 

quit = False 

blocksize = 1<<16 # 64kB 
blocksperchunk = 1<<10 

chunksize = blocksize * blocksperchunk 

def handler(signum, frame): 
    global quit 
    print "\nGot signal %d, cleaning up." % signum 
    quit = True 


def do_hash(fname): 
    hashname = fname + '.hash' 
    if os.path.exists(hashname): 
     with open(hashname, 'rt') as f: 
      data = f.read().split() 
     pos = int(data[0]) 
     current = data[1].decode('hex') 
    else: 
     pos = 0 
     current = '' 

    finished = False 
    with open(fname, 'rb') as f: 
     f.seek(pos) 
     while not (quit or finished): 
      full = hashlib.sha256(current) 
      part = hashlib.sha256() 
      for _ in xrange(blocksperchunk): 
       block = f.read(blocksize) 
       if block == '': 
        finished = True 
        break 
       part.update(block) 

      full.update(part.digest()) 
      current = full.digest() 
      pos += chunksize 
      print pos 
      if finished or quit: 
       break 

    hexdigest = full.hexdigest() 
    if quit: 
     with open(hashname, 'wt') as f: 
      f.write("%d %s\n" % (pos, hexdigest)) 
    elif os.path.exists(hashname): 
     os.remove(hashname)  

    return (not quit), pos, hexdigest 


def main(): 
    if len(sys.argv) != 2: 
     print "Calculate resumable hash of a file." 
     print "Usage:\npython %s filename\n" % sys.argv[0] 
     exit(1) 

    fname = sys.argv[1] 

    signal.signal(signal.SIGINT, handler) 
    signal.signal(signal.SIGTERM, handler) 

    print do_hash(fname) 


if __name__ == '__main__': 
    main() 
Смежные вопросы