栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

持续使用sha256哈希对象?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

持续使用sha256哈希对象?

事实证明,比起我想重写hashlib至少要恢复SHA-256部分要容易得多。我花了一些时间玩使用OpenSSL加密库的C代码,但是后来我意识到我并不需要所有这些东西,我可以只使用ctypes。

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

编辑

rehash
尽管我只在WinXP上进行了测试,但我也做了一些小的编辑以允许在Windows上工作。本
libeay32.dll
可以在当前目录下,或者在系统库搜索路径,如某处
WINDOWSsystem32
。即使OpenOffice和Avira使用了.dll,我的安装也相当古老(并且几乎未使用),但找不到.dll。因此,我只是将其从Avira文件夹复制到了system32。现在,它可以完美运行。:)



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/470497.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号