> ## Documentation Index
> Fetch the complete documentation index at: https://ahvn.top/llms.txt
> Use this file to discover all available pages before exploring further.

# Hash

> Deterministic hash helpers for identifiers, buckets, and fingerprints.

<Note>
  *"All is number." — Pythagoras*
</Note>

Use these helpers when you need one hash entry point for scalars, collections, Python objects, callables, and other HeavenBase values.

<br />

## 1. Why Unified Hashing Exists

HeavenBase derives IDs, buckets, cache keys, and fingerprints from many different value kinds — ints, strings, lists, dicts, dataclass rows, Python functions, capsules, MCP tools, and more. Without a shared encoder layer, every call site ends up with its own serialization rule:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# Anti-pattern: one-off encoders per value kind
import hashlib
import json

def make_id(value):
    if isinstance(value, str):
        payload = value
    elif isinstance(value, dict):
        payload = json.dumps(value, sort_keys=True)
    elif callable(value):
        payload = f"{value.__module__}.{value.__qualname__}"
    else:
        payload = repr(value)
    return hashlib.md5(payload.encode()).hexdigest()
```

That pattern fragments quickly. A dict row, a toolkit definition, and a callable capsule each need different encoding logic, and optional namespacing salt becomes another ad-hoc concatenation rule.

HeavenBase wraps standard digests — MD5, SHA-256, and CRC32 — with a shared encoder and optional `salt`. The encoder normalizes common Python values (including structured objects and callables) into a deterministic string before hashing; `hash_id(...)` is the namespaced front door when several logical parts should hash together:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from heavenbase.utils import crc32hash, hash_id, hash_int, md5hash

# Same API for scalars, collections, and structured objects
row_id = md5hash({"source": "docs", "name": "Ada"})
entity_id = hash_id("document", "Ada")

# Callables hash through the same encoder path
tool_id = md5hash(my_callable)

# Salt namespaces a digest without changing the value encoding
cache_key = md5hash(large_payload, salt="llm-cache-v2")
gram_weight = crc32hash("redis query", salt="heavenbase.gram.v1")
sample_weight = hash_int("row-17", method="crc32")
```

One import path covers identifiers, modulo buckets, cache keys, and fingerprints across the types HeavenBase already moves through JSON, databases, catalogs, toolkits, and capsules. You do not need to choose a different hashing strategy every time the input shape changes.

<Warning>
  Unified hashing serializes input before digesting. That is inexpensive for scalars and small dicts, but hashing a huge volume of large, deeply nested objects — or callables that trigger full source serialization — can add noticeable overhead. Profile hot paths that hash millions of heavyweight payloads.
</Warning>

<Info>
  These helpers are deterministic utility hashes, not authentication or password-storage primitives.
</Info>

<br />

## 2. Core Idea

HeavenBase often needs identifiers that behave like strings because they move through JSON, database rows, object IDs, and filenames. It also sometimes benefits from values that can be interpreted as integers for ordering, bucket assignment, or index-friendly storage.

`md5hash(...)` and `crc32hash(...)` return zero-padded decimal strings. That means they can live as normal string IDs, but same-length values also sort like their integer representation. `crc32hash(...)` defaults to length `10`; `md5hash(...)` defaults to length `42`.

<Info>
  This is not settled as a universal design. The integer-able string hash is a practical compatibility move for the current pre-release, not a claim that every external API should depend on this exact representation. We are still exploring the best way to achieve stability and generic usability.
</Info>

<br />

## 3. Create a Stable ID

`md5hash(...)` serializes common Python values with stable JSON ordering and returns a zero-padded decimal string. The default length is `42`, which matches HeavenBase's identifier-friendly hash width.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from heavenbase.utils import md5hash

row_id = md5hash({"source": "docs", "name": "Ada"})
same_id = md5hash({"name": "Ada", "source": "docs"})

assert row_id == same_id
```

Use `hash_id(...)` when an ID should carry a logical namespace:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from heavenbase.utils import hash_id

prompt_id = hash_id("prompt", "demo.greet", "1")
```

<br />

## 4. Bucket or Order Values

Use integer digests when modulo arithmetic, deterministic sampling, sparse weights, or ordering needs a number. Use `hash_int(...)` or `resolve_hash_int(...)` when the method is runtime policy rather than a fixed ID contract.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from heavenbase.utils import crc32int, hash_int, md5int, resolve_hash_int, sha256int

bucket = md5int("workspace-alpha") % 16
gram_bucket = crc32int("redis query", salt="heavenbase.gram.v1") % 1024
wide_bucket = sha256int({"workspace": "alpha", "entity": "person"}) % 1024
policy_bucket = hash_int("candidate-row", method="crc32") % 1024
same_policy = resolve_hash_int("crc32")("candidate-row") % 1024
```

`resolve_hash_int(...)` accepts `md5`, `sha256`, `crc32`, optional `xxhash64` / `xxhash128` when the `xxhash` package is installed, and dotted callables with the signature `fn(obj, salt=None, sep="||") -> int`.

`crc32int(...)` is the cheapest deterministic stdlib option and is used by the Sparse GRAM runtime for trigram weights and sparse-span hashes in SQL-hosted `SparseGramIndex` and the explicit compatibility `gram` backend. Exact keyword verification protects query correctness when CRC32 collisions widen the candidate set. `md5int(...)` is still useful for local utility IDs, and `sha256int(...)` is useful when a wider digest makes the intent clearer.

Keep persisted identity and integrity surfaces pinned to explicit helpers: `hash_id(...)` / `md5hash(...)` for existing object IDs, and `sha256hash(...)` for fingerprints and cache correctness boundaries. CRC32 is the default policy for candidate generation and deterministic sampling because those paths exact-verify or tolerate changed sample choice.

<br />

## 5. Fingerprint Larger Payloads

Use `sha256hash(...)` for hex fingerprints in manifests, config snapshots, and integrity checks.

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from heavenbase.utils import fmt_short_hash, sha256hash

fingerprint = sha256hash({"model": "ds-flash", "temperature": 0})
display = fmt_short_hash(fingerprint, length=10)
```

<Info>
  These helpers are deterministic utility hashes, not authentication or password-storage primitives.
</Info>

<br />

## Further Exploration

<Tip>
  **Related resources:**

  * [Random](/features/utilities/random) - deterministic seed evolution and hash-based sampling.
  * [File System](/features/utilities/file-system) - serialization helpers used before hashing structured data.
  * [Catalog](/features/catalog) - object IDs and discoverable names.
</Tip>

<br />
