持久性hashlib状态

持久性hashlib状态,第1张

持久性hashlib状态

您可以使用来以这种方式进行 *** 作

ctypes
,不需要 C中的 辅助应用程序

rehash.py

#! /usr/bin/env python''' A resumable implementation of SHA-256 using ctypes with the OpenSSL crypto library    Written by PM 2Ring 2014.11.13'''from ctypes import *SHA_LBLOCK = 16SHA256_DIGEST_LENGTH = 32class SHA256_CTX(Structure):    _fields_ = [        ("h", c_long * 8),        ("Nl", c_long),        ("Nh", c_long),        ("data", c_long * SHA_LBLOCK),        ("num", c_uint),        ("md_len", c_uint)    ]HashBuffType = c_ubyte * SHA256_DIGEST_LENGTH#crypto = cdll.LoadLibrary("libcrypto.so")crypto = cdll.LoadLibrary("libeay32.dll" if os.name == "nt" else "libssl.so")class sha256(object):    digest_size = SHA256_DIGEST_LENGTH    def __init__(self, datastr=None):        self.ctx = SHA256_CTX()        crypto.SHA256_Init(byref(self.ctx))        if datastr: self.update(datastr)    def update(self, datastr):        crypto.SHA256_Update(byref(self.ctx), datastr, c_int(len(datastr)))    #Clone the current context    def _copy_ctx(self):        ctx = SHA256_CTX()        pointer(ctx)[0] = self.ctx        return ctx    def copy(self):        other = sha256()        other.ctx = self._copy_ctx()        return other    def digest(self):        #Preserve context in case we get called before hashing is        # really finished, since SHA256_Final() clears the SHA256_CTX        ctx = self._copy_ctx()        hashbuff = HashBuffType()        crypto.SHA256_Final(hashbuff, byref(self.ctx))        self.ctx = ctx        return str(bytearray(hashbuff))    def hexdigest(self):        return self.digest().enpre('hex')#Testsdef main():    import cPickle    import hashlib    data = ("Nobody expects ", "the spammish ", "imposition!")    print "rehashn"    shaA = sha256(''.join(data))    print shaA.hexdigest()    print repr(shaA.digest())    print "digest size =", shaA.digest_size    print    shaB = sha256()    shaB.update(data[0])    print shaB.hexdigest()    #Test pickling    sha_pickle = cPickle.dumps(shaB, -1)    print "Pickle length:", len(sha_pickle)    shaC = cPickle.loads(sha_pickle)    shaC.update(data[1])    print shaC.hexdigest()    #Test copying. Note that copy can be pickled    shaD = shaC.copy()    shaC.update(data[2])    print shaC.hexdigest()    #Verify against hashlib.sha256()    print "nhashlibn"    shaD = hashlib.sha256(''.join(data))    print shaD.hexdigest()    print repr(shaD.digest())    print "digest size =", shaD.digest_size    print    shaE = hashlib.sha256(data[0])    print shaE.hexdigest()    shaE.update(data[1])    print shaE.hexdigest()    #Test copying. Note that hashlib copy can NOT be pickled    shaF = shaE.copy()    shaF.update(data[2])    print shaF.hexdigest()if __name__ == '__main__':    main()

resumable_SHA-256.py

#! /usr/bin/env python''' Resumable SHA-256 hash for large files using the OpenSSL crypto library    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 current file position, total file size, and    the sha object 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.14'''import cPickle as pickleimport osimport signalimport sysimport rehashquit = Falseblocksize = 1<<16   # 64kBblocksperchunk = 1<<8chunksize = blocksize * blocksperchunkdef handler(signum, frame):    global quit    print "nGot signal %d, cleaning up." % signum    quit = Truedef do_hash(fname, filesize):    hashname = fname + '.hash'    if os.path.exists(hashname):        with open(hashname, 'rb') as f: pos, fsize, sha = pickle.load(f)        if fsize != filesize: print "Error: file size of '%s' doesn't match size recorded in '%s'" % (fname, hashname) print "%d != %d. Aborting" % (fsize, filesize) exit(1)    else:        pos, fsize, sha = 0, filesize, rehash.sha256()    finished = False    with open(fname, 'rb') as f:        f.seek(pos)        while not (quit or finished): for _ in xrange(blocksperchunk):     block = f.read(blocksize)     if block == '':         finished = True         break     sha.update(block) pos += chunksize sys.stderr.write(" %6.2f%% of %dr" % (100.0 * pos / fsize, fsize)) if finished or quit:     break    if quit:        with open(hashname, 'wb') as f: pickle.dump((pos, fsize, sha), f, -1)    elif os.path.exists(hashname):        os.remove(hashname)    return (not quit), pos, sha.hexdigest()def main():    if len(sys.argv) != 2:        print "Resumable SHA-256 hash of a file."        print "Usage:npython %s filenamen" % sys.argv[0]        exit(1)    fname = sys.argv[1]    filesize = os.path.getsize(fname)    signal.signal(signal.SIGINT, handler)    signal.signal(signal.SIGTERM, handler)    finished, pos, hexdigest = do_hash(fname, filesize)    if finished:        print "%s  %s" % (hexdigest, fname)    else:        print "sha-256 hash of '%s' incomplete" % fname        print "%s" % hexdigest        print "%d / %d bytes processed." % (pos, filesize)if __name__ == '__main__':    main()

演示

import rehashimport picklesha=rehash.sha256("Hello ")s=pickle.dumps(sha.ctx)sha=rehash.sha256()sha.ctx=pickle.loads(s)sha.update("World")print sha.hexdigest()

输出

a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e

注意:我要感谢PM2Ring的出色代码。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5667644.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存