def _recursive_hash(
    value: Union[dict, list, str, int, bool, float, complex, None],
    ignore_none=False,
) -> str:
    """Hash a json-like structure. Implementation is simplified from merkle_json.

    Args:
        value (Union[dict, list, str, int, bool, float, complex, None]): The value or object to hash.
        ignore_none (bool, optional): If provided, ignore None values in the hash. Defaults to False.

    Returns:
        str: The hash of the value.
    """
    if isinstance(value, list):
        h_acc = [_recursive_hash(v, ignore_none) for v in value]
        return _recursive_hash("".join(sorted(h_acc)), ignore_none)
    elif isinstance(value, dict):
        keys = sorted(value.keys())
        acc = ""
        for k in keys:
            key_val = value[k]
            if ignore_none and key_val is None:
                continue

            acc += f"{k}:{_recursive_hash(key_val, ignore_none=ignore_none)},"
        return _recursive_hash(acc, ignore_none=ignore_none)
    else:
        return hashlib.md5(str(value).encode("utf-8")).hexdigest()
Hash a json-like structure. Implementation is simplified from merkle_json.

    Args:
        value (Union[dict, list, str, int, bool, float, complex, None]): The value or object to hash.
        ignore_none (bool, optional): If provided, ignore None values in the hash. Defaults to False.

    Returns:
        str: The hash of the value.
    
src/core/trulens/core/utils/json.py