持久化 hashlib 状态

2023-11-22

我想创建一个hashlib实例,update()然后以某种方式保留其状态。稍后,我想使用此状态数据重新创建对象,并继续update()它。最后,我想得到hexdigest()数据的总累积运行。状态持久性必须在多次运行中保持不变。

Example:

import hashlib
m = hashlib.sha1()
m.update('one')
m.update('two')
# somehow, persist the state of m here

#later, possibly in another process
# recreate m from the persisted state
m.update('three')
m.update('four')
print m.hexdigest()
# at this point, m.hexdigest() should be equal to hashlib.sha1().update('onetwothreefour').hextdigest()

EDIT:

2010 年,我没有找到使用 python 实现此目的的好方法,最终用 C 语言编写了一个小型辅助应用程序来实现此目的。然而,下面有一些我当时无法获得或不知道的很好的答案。


你可以用这种方式做到这一点ctypes,没有帮助应用程序C需要:-

重新散列.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 = 16
SHA256_DIGEST_LENGTH = 32

class 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().encode('hex')

#Tests
def main():
    import cPickle
    import hashlib

    data = ("Nobody expects ", "the spammish ", "imposition!")

    print "rehash\n"

    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 "\nhashlib\n"

    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()

可恢复_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 pickle
import os
import signal
import sys

import rehash

quit = False

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

chunksize = blocksize * blocksperchunk

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


def 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 %d\r" % (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 filename\n" % 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()

demo

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

output

a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e

注意:我要感谢 PM2Ring 提供的精彩代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

持久化 hashlib 状态 的相关文章

  • 在 python 程序中合并第三方库的最佳实践是什么?

    下午好 我正在为我的工作编写一个中小型Python程序 该任务需要我使用 Excel 库xlwt and xlrd 以及一个用于查询 Oracle 数据库的库 称为CX Oracle 我正在通过版本控制系统 即CVS 开发该项目 我想知道围
  • 使 django 服务器可以在 LAN 中访问

    我已经安装了Django服务器 可以如下访问 http localhost 8000 get sms http 127 0 0 1 8000 get sms 假设我的IP是x x x x 当我这样做时 从同一网络下的另一台电脑 my ip
  • python 相当于 R 中的 get() (= 使用字符串检索符号的值)

    在 R 中 get s 函数检索名称存储在字符变量 向量 中的符号的值s e g X lt 10 r lt XVI s lt substr r 1 1 X get s 10 取罗马数字的第一个符号r并将其转换为其等效整数 尽管花了一些时间翻
  • 测试 python Counter 是否包含在另一个 Counter 中

    如何测试是否是pythonCounter https docs python org 2 library collections html collections Counter is 包含在另一个中使用以下定义 柜台a包含在计数器中b当且
  • 基于代理的模拟:性能问题:Python vs NetLogo & Repast

    我正在 Python 3 中复制一小段 Sugarscape 代理模拟模型 我发现我的代码的性能比 NetLogo 慢约 3 倍 这可能是我的代码的问题 还是Python的固有限制 显然 这只是代码的一个片段 但 Python 却花费了三分
  • OpenCV 无法从 MacBook Pro iSight 捕获

    几天后 我无法再从 opencv 应用程序内部打开我的 iSight 相机 cap cv2 VideoCapture 0 返回 并且cap isOpened 回报true 然而 cap grab 刚刚返回false 有任何想法吗 示例代码
  • 绘制方程

    我正在尝试创建一个函数 它将绘制我告诉它的任何公式 import numpy as np import matplotlib pyplot as plt def graph formula x range x np array x rang
  • 从 Flask 访问 Heroku 变量

    我已经使用以下命令在 Heroku 配置中设置了数据库变量 heroku config add server xxx xxx xxx xxx heroku config add user userName heroku config add
  • .NET 中是否有内置函数可以对密码进行哈希处理?

    我看到这个问题加密 散列数据库中的纯文本密码 https stackoverflow com questions 287517 encrypting hashing plain text passwords in database 我知道我
  • 在Python中获取文件描述符的位置

    比如说 我有一个原始数字文件描述符 我需要根据它获取文件中的当前位置 import os psutil some code that works with file lp lib open path to file p psutil Pro
  • IO 密集型任务中的 Python 多线程

    建议仅在 IO 密集型任务中使用 Python 多线程 因为 Python 有一个全局解释器锁 GIL 只允许一个线程持有 Python 解释器的控制权 然而 多线程对于 IO 密集型操作有意义吗 https stackoverflow c
  • Fabric env.roledefs 未按预期运行

    On the 面料网站 http docs fabfile org en 1 10 usage execution html 给出这个例子 from fabric api import env env roledefs web hosts
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 如何在seaborn displot中使用hist_kws

    我想在同一图中用不同的颜色绘制直方图和 kde 线 我想为直方图设置绿色 为 kde 线设置蓝色 我设法弄清楚使用 line kws 来更改 kde 线条颜色 但 hist kws 不适用于显示 我尝试过使用 histplot 但我无法为
  • 对年龄列进行分组/分类

    我有一个数据框说df有一个柱子 Ages gt gt gt df Age 0 22 1 38 2 26 3 35 4 35 5 1 6 54 我想对这个年龄段进行分组并创建一个像这样的新专栏 If age gt 0 age lt 2 the
  • 如何计算 pandas 数据帧上的连续有序值

    我试图从给定的数据帧中获取连续 0 值的最大计数 其中包含来自 pandas 数据帧的 id date value 列 如下所示 id date value 354 2019 03 01 0 354 2019 03 02 0 354 201
  • 使用其构造函数初始化 OrderedDict 以便保留初始数据的顺序的正确方法?

    初始化有序字典 OD 以使其保留初始数据的顺序的正确方法是什么 from collections import OrderedDict Obviously wrong because regular dict loses order d O
  • Python 类继承 - 诡异的动作

    我观察到类继承有一个奇怪的效果 对于我正在处理的项目 我正在创建一个类来充当另一个模块的类的包装器 我正在使用第 3 方 aeidon 模块 用于操作字幕文件 但问题可能不太具体 以下是您通常如何使用该模块 project aeidon P
  • Python Selenium:如何在文本文件中打印网站上的值?

    我正在尝试编写一个脚本 该脚本将从 tulsaspca org 网站获取以下 6 个值并将其打印在 txt 文件中 最终输出应该是 905 4896 7105 23194 1004 42000 放置的动物 的 HTML span class
  • 如何将输入读取为数字?

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 Why are x and y下面的代码中使用字符串而不是整数 注意 在Python 2

随机推荐

  • 在 Raku 中使用 Perl 5 模块 Data::Printer 的 `show_tied` 选项时,如何关闭它?

    我使用了带有 Perl 的 CPAN Perl 模块 Data Printer DP 效果很好 现在我想在 Raku 代码中使用它 When I use the from
  • Kivy:标签文本在 for 循环期间不会更新

    当我尝试在 for 循环期间更新标签文本时遇到问题 还有类似的条目 例如 运行代码时更新 kivy 小部件的属性 但它们似乎并不完全符合我的问题 或者我错过了重点 我运行以下代码 py from kivy app import App fr
  • C# 创建/修改/读取 .xlsx 文件

    我正在寻找一种在 C 中创建 修改 读取 xlsx 文件的方法 而无需安装 Excel 或在服务器上创建文件 然后再提供给用户下载 我找到了NPOIhttp npoi codeplex com 看起来不错 但支持 xls 而不是 xlsx
  • 32 位字的镜像位

    你会如何在 C 中做到这一点 例如 如果我们必须镜像 8 位 则 10110001 会变为 10001101 某些处理器上是否有任何指令可以简化此任务 它实际上被称为 位反转 通常在 FFT 加扰中完成 O log N 方式是 最多 32
  • perl6 可以在匹配中使用连接吗?

    是否可以使用 junction 来匹配 junction 中的任何值 我想匹配数组中的任何值 正确的做法是什么 lisprog perl6 To exit type exit or D gt my a a a b c gt any a an
  • 检查项目是否已在上下文菜单中[重复]

    这个问题在这里已经有答案了 不久前 我可以在 Google Chrome 扩展中保存上下文菜单中创建的项目的 ID 背景 js var myItem if myItem MyItem myItem chrome contextMenus c
  • 使用 CRON 作业访问 url?

    我有一个网络应用程序 必须执行重复的任务 发送消息和警报 我已经使用脚本页面在浏览器中加载时执行这些任务 即http example com tasks php我通过 iframe 将其包含在我的 Web 应用程序的每个页面中 现在我想改变
  • Android 请求多个权限

    我正在修改现有的面部跟踪器应用程序 Android 的面部识别示例项目 我在请求多个永久权限时遇到问题 下面的方法是现有方法的修改版本 成功创建了一个弹出窗口来请求相机权限 我正在尝试使用存储权限来复制此内容 但到目前为止我还没有成功 并且
  • 如何通过API获取维基百科文章的一小段文字和主图?

    我正在尝试创建一个简单的维基百科克隆 允许用户搜索某个主题 然后显示 10 个包含文章图像和一小段文本的结果 我已经能够将用户提供的搜索字段传递给我的 ajax 打电话没有问题 但现在我无法检索图像 我已经阅读了 StackOverflow
  • 将线程分配给特定的CPU核心

    AFAIK 在 Linux 中可以将线程分配给 CPU 核心 看this 但是 我的问题是我可以使用以下方法实现此功能吗boost如果可能的话 又是如何实现的呢 请注意 操作系统也不能决定哪个对我来说更好 而是假设我想在设计中控制这种行为
  • Java 通过谓词将流拆分为流的流

    我正在阅读数百个大型 6GB gzip 日志文件GZIPInputStream是我想解析的 假设每一项的格式如下 Start of log entry 1 some log details some log details some log
  • 在 BigQuery 中查询多个重复字段

    我有一个架构 其中包含多个未嵌套的重复字段 我正在尝试查询叉积 但出现错误 无法查询重复字段的叉积 如果我只查询 2 个重复字段 我可以将其中之一展平 然而 我有兴趣查询超过 2 个重复字段 并且我无法理解 FLATTEN 语法如何支持这一
  • 如何将 Android Studio 完全安装到非默认 (D:) 驱动器

    我将从高级 常识 问题开始 然后进入技术细节 高级问题 在 Windows 10 中运行 Android Studio 安装程序时 我告诉它安装到 D 驱动器 而不是默认的 C 驱动器 为什么它坚持将某些组件安装到 C 驱动器上 安装到非默
  • 在 Java Web 应用程序中加载外部库

    我的场景如下 我有一个部署到 servlet 容器的 WebApp war 此 WebApp war 在 WEB INF lib 中包含以下库 lib a jar lib b jar 我还有另一个库 例如 lib vendor jar 由于
  • 在 xcode 中仍然出现 文件未找到错误

    我是 PhoneGap 的新手 通过 Xcode 制作应用程序 但我发现了一个错误CDVViewController h 然而 该文件实际上存在于那里 我正在使用 Xcode 4 6 和 Cordova 2 2 0 伙计 这个问题有很多转移
  • AWS ECS 运行任务时出错:在集群中找不到容器实例

    我正在尝试部署一个docker容器镜像到AWS using ECS 但未创建 EC2 实例 我在互联网上搜索了有关为什么收到以下错误的解释 调用 RunTask 操作时发生客户端错误 InvalidParameterException 在集
  • 为什么使用 0 作为“停止”的切片表示法反转列表不会返回整个列表?

    在以下示例中 foo red white blue 1 2 3 foo 0 6 1 将打印所有元素foo 然而 foo 6 0 i 1 将省略第 1 个或第 0 个元素 gt gt gt foo 6 0 1 3 2 1 blue white
  • 在 R 公式中使用带有特殊字符的列

    我正在尝试使用 rpart 使用大约 200 列的数据框来制作决策树 其中一些列的名称中包含数字 一些列的名称中包含特殊字符 例如 当我尝试生成树时 出现如下错误 R gt gg rpart lt rpart nospecialchar S
  • Oracle 中的 Unique 与 Distinct 关键字

    我对这些词的用法有点困惑 我有一个包含以下列的表格 站点 纬度 长 名称 我想要具有独特 或不同 LAT LONG 的结果 我该如何实现这一目标 select unique colA colB from atable select dist
  • 持久化 hashlib 状态

    我想创建一个hashlib实例 update 然后以某种方式保留其状态 稍后 我想使用此状态数据重新创建对象 并继续update 它 最后 我想得到hexdigest 数据的总累积运行 状态持久性必须在多次运行中保持不变 Example i