您可以使用来以这种方式进行 *** 作
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的出色代码。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)