Skip to content

Instantly share code, notes, and snippets.

@artoby
Last active July 25, 2024 09:30
Show Gist options
  • Save artoby/49c4d24e28a49f01728a5b4e7e53798a to your computer and use it in GitHub Desktop.
Save artoby/49c4d24e28a49f01728a5b4e7e53798a to your computer and use it in GitHub Desktop.
Hashing of an arbitrary Python object so that it can be used for cache identification or other hash-related use cases. Produces either bytes or a string
from typing import Any, Optional
import hashlib
import base64
import json
def get_hash_bytes(value: Any, hash_bytes=10, salt=None) -> Optional[bytes]:
"""
param hash_bytes: how many bytes to hake for the trimmed hash, 10 bytes of data -> 16 symbols string
"""
if value is None:
return None
if hash_bytes <= 0:
raise ValueError(f'Hash bytes value should be >0, but not "{hash_bytes}", ignoring it')
value_str = json.dumps(value, sort_keys=True)
if (salt is not None) and (salt != ''):
value_str = value_str + salt
s_bytes = value_str.encode('utf-8')
hash_result = hashlib.sha1(s_bytes)
bytes_taken = hash_result.digest() if hash_bytes is None else hash_result.digest()[-hash_bytes:]
return bytes_taken
def get_hash(value: Any, hash_bytes=10, salt=None) -> Optional[str]:
"""
Hashing of an arbitrary Python object so that it can be used for cache identification or other hash-related use cases.
Source https://gist.github.com/artoby/49c4d24e28a49f01728a5b4e7e53798a
"""
bytes_taken = get_hash_bytes(value=value, hash_bytes=hash_bytes, salt=salt)
if bytes_taken is None:
return None
result = base64.b32encode(bytes_taken).decode('utf-8').rstrip('=')
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment