我如何从Python中派生出hashlib.sha256?
| 
                         
 天真的尝试失败了: 
  
  
  
import hashlib
class fred(hashlib.sha256):
    pass
-> TypeError: Error when calling the metaclass bases
       cannot create 'builtin_function_or_method' instances 
 好吧,事实证明hashlib.sha256是一个可调用的,而不是一个类.尝试更有创意的东西也不起作用: import hashlib
 class fred(type(hashlib.sha256())):
     pass
 f = fred
 -> TypeError: cannot create 'fred' instances 
 嗯… 那么,我该怎么做? 这是我想要实际实现的目标: class shad_256(sha256):
    """Double SHA - sha256(sha256(data).digest())
Less susceptible to length extension attacks than sha256 alone."""
    def digest(self):
        return sha256(sha256.digest(self)).digest()
    def hexdigest(self):
        return sha256(sha256.digest(self)).hexdigest() 
 基本上我希望一切都能通过,除非有人要求结果我想插入我自己的额外步骤.是否有一种聪明的方法可以用__new__或某种类型的元类魔法来实现这一目标? 我有一个解决方案,我很满意我发布的答案,但我真的很想知道是否有人能想到更好的东西.要么更简洁,可读性成本非常低,要么更快(特别是在调用更新时),同时仍具有一定的可读性. 更新:我运行了一些测试: # test_sha._timehash takes three parameters,the hash object generator to use,# the number of updates and the size of the updates. # Built in hashlib.sha256 $python2.7 -m timeit -n 100 -s 'import test_sha,hashlib' 'test_sha._timehash(hashlib.sha256,20000,512)' 100 loops,best of 3: 104 msec per loop # My wrapper based approach (see my answer) $python2.7 -m timeit -n 100 -s 'import test_sha,hashlib' 'test_sha._timehash(test_sha.wrapper_shad_256,best of 3: 108 msec per loop # Glen Maynard's getattr based approach $python2.7 -m timeit -n 100 -s 'import test_sha,hashlib' 'test_sha._timehash(test_sha.getattr_shad_256,best of 3: 103 msec per loop 解决方法
 只需使用__getattr__使您自己未定义的所有属性都回退到底层对象: 
  
  
  
        import hashlib
class shad_256(object):
    """
    Double SHA - sha256(sha256(data).digest())
    Less susceptible to length extension attacks than sha256 alone.
    >>> s = shad_256('hello world')
    >>> s.digest_size
    32
    >>> s.block_size
    64
    >>> s.sha256.hexdigest()
    'b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9'
    >>> s.hexdigest()
    'bc62d4b80d9e36da29c16c5d4d9f11731f36052c72401a76c23c0fb5a9b74423'
    >>> s.nonexistant()
    Traceback (most recent call last):
    ...
    AttributeError: '_hashlib.HASH' object has no attribute 'nonexistant'
    >>> s2 = s.copy()
    >>> s2.digest() == s.digest()
    True
    >>> s2.update("text")
    >>> s2.digest() == s.digest()
    False
    """
    def __init__(self,data=None):
        self.sha256 = hashlib.sha256()
        if data is not None:
            self.update(data)
    def __getattr__(self,key):
        return getattr(self.sha256,key)
    def _get_final_sha256(self):
        return hashlib.sha256(self.sha256.digest())
    def digest(self):
        return self._get_final_sha256().digest()
    def hexdigest(self):
        return self._get_final_sha256().hexdigest()
    def copy(self):
        result = shad_256()
        result.sha256 = self.sha256.copy()
        return result
if __name__ == "__main__":
    import doctest
    doctest.testmod() 
 这主要消除了更新调用的开销,但并非完全消除.如果要完全消除它,请将其添加到__init__(并相应地复制): self.update = self.sha256.update 在查找更新时,这将消除额外的__getattr__调用. 这一切都利用了Python成员函数中一个更有用且经常被忽略的属性:函数绑定.回想一下,你可以这样做: a = "hello" b = a.upper b() 因为对成员函数的引用不会返回原始函数,而是返回该函数与其对象的绑定.这就是为什么,当__getattr__返回self.sha256.update时,返回的函数正确地在self.sha256上运行,而不是self. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!  | 
                  
