Source code for cotk._utils.unordered_hash

'''
A module for hash unordered elements
'''

from typing import Union
from collections import OrderedDict
import hashlib
import json
import warnings


[docs]class UnorderedSha256: ''' Using SHA256 on unordered elements ''' def __init__(self): self.result = [0] * 32
[docs] def update_data(self, data: Union[bytes, bytearray, memoryview]): '''update digest by data. type(data)=bytes''' digest = hashlib.sha256(data).digest() self.update_hash(digest)
[docs] def update_hash(self, hashvalue): '''update digest by hash. type(hashvalue)=bytes''' for i, bit in enumerate(list(hashvalue)): self.result[i] = (self.result[i] + bit) & 0xFF
[docs] def digest(self) -> bytes: '''return unordered hashvalue''' return bytes(self.result)
[docs] def hexdigest(self) -> str: '''return unordered hashvalue''' return bytes(self.result).hex()
[docs]def dumps_json(obj) -> bytes: '''Generate bytes to identify the object by json serialization''' if isinstance(obj, (str, int, float, bool)): return str(obj).encode('utf-8') return json.dumps(obj, sort_keys=True).encode('utf-8')
[docs]def dumps(obj) -> bytes: '''Generate bytes to identify the object by repr''' return simple_dumps(convert_obj(obj))
def simple_dumps(obj) -> bytes: return repr(obj).encode('utf-8') def convert_obj(obj): if isinstance(obj, OrderedDict): return convert_ordered_dict(obj) for cls, func in special_type_processing_functions.items(): if isinstance(obj, cls): return func(obj) if not isinstance(obj, common_types): warnings.warn("It's unsupported to dumps a %s object. The result may not be expected." % type(obj).__name__) return obj def convert_dict(obj): return type(obj), [(convert_obj(k), convert_obj(v)) for k, v in sorted(obj.items())] def convert_ordered_dict(obj): return type(obj), [(convert_obj(k), convert_obj(v)) for k, v in obj.items()] def convert_ordered_iterable(obj): return type(obj), [convert_obj(item) for item in obj] def convert_unordered_iterable(obj): # Elements in a set or a frozenset is unordered. Sort them before dumps. return type(obj), [convert_obj(item) for item in sorted(obj)] special_type_processing_functions = { tuple: convert_ordered_iterable, list: convert_ordered_iterable, set: convert_unordered_iterable, frozenset: convert_unordered_iterable, dict: convert_dict, OrderedDict: convert_ordered_dict } common_types = (str, int, float, bytes, bytearray, bool, type, type(None))