5

hashlibインスタンスを作成しupdate()て、その状態を何らかの方法で永続化したいと思います。後で、この状態データを使用してオブジェクトを再作成し、続行したいと思いますupdate()hexdigest()最後に、データの累積実行の合計を取得したいと思います。状態の永続性は、複数の実行にわたって存続する必要があります。

例:

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

編集:

私は2010年にPythonでこれを行うための良い方法を見つけられず、これを達成するためにCで小さなヘルパーアプリを書くことになりました。ただし、その時点では利用できなかった、または知られていない、いくつかの優れた回答が以下にあります。

4

5 に答える 5

1

hashlib.sha1 は C ライブラリのラッパーなので、ピクルすることはできません。

内部状態にアクセスするには、Pythonの メソッド__getstate__とメソッドを実装する必要があります。__setstate__

sha1 の純粋な Python実装が要件に対して十分に高速である場合は、それを使用できます。

于 2010-01-25T08:03:13.213 に答える
0

動的成長/ストリーミングデータのハッシュアルゴリズム?

于 2011-05-04T07:35:42.590 に答える
-1

データを透過的に永続化できるハッシュ オブジェクトの周りにラッパー オブジェクトを簡単に作成できます。

明らかな欠点は、状態を復元するためにハッシュ化されたデータを完全に保持する必要があることです。そのため、扱うデータのサイズによっては、これがニーズに合わない場合があります。ただし、数十 MB までは正常に動作するはずです。

残念ながら、hashlib はハッシュ アルゴリズムを適切なクラスとして公開せず、むしろハッシュ オブジェクトを構築するファクトリ関数を提供します。これは、最初からラッパー クラスを作成する必要があることを意味するだけであり、とにかく Python のオーバーヘッドほどではありません。

ここにあなたのニーズを満たすかもしれないサンプルコードがあります:

import hashlib
from cStringIO import StringIO

class PersistentSha1(object):
    def __init__(self, salt=""):
        self.__setstate__(salt)

    def update(self, data):
        self.__data.write(data)
        self.hash.update(data)

    def __getattr__(self, attr):
        return getattr(self.hash, attr)

    def __setstate__(self, salt=""):
        self.__data = StringIO()
        self.__data.write(salt)
        self.hash = hashlib.sha1(salt)

    def __getstate__(self):
        return self.data

    def _get_data(self):
        self.__data.seek(0)
        return self.__data.read()

    data = property(_get_data, __setstate__)

「データ」メンバー自体にアクセスして、状態を直接取​​得および設定するか、python pickling 関数を使用できます。

>>> a = PersistentSha1()
>>> a
<__main__.PersistentSha1 object at 0xb7d10f0c>
>>> a.update("lixo")
>>> a.data
'lixo'
>>> a.hexdigest()
'6d6332a54574aeb35dcde5cf6a8774f938a65bec'
>>> import pickle
>>> b = pickle.dumps(a)
>>>
>>> c = pickle.loads(b)
>>> c.hexdigest()
'6d6332a54574aeb35dcde5cf6a8774f938a65bec'

>>> c.data
'lixo'
于 2010-01-25T12:30:01.067 に答える