Skip to main content

Generate compact human-facing references from ULIDs, UUIDs, and other stable identifiers

Project description

CompactRef

Generate compact, human-facing references from ULIDs, UUIDs and other stable internal identifiers.

CompactRef is useful when an application keeps a full internal identifier but needs a shorter reference for users, support teams, documents or searches.

Installation

pip install compactref

Generate a reference from a ULID

from compactref import generate_reference

reference = generate_reference(
    "01J2H8NQPG6B5X8KGN97SX3R5C",
)

print(reference)

Possible output:

20260710482731

Add a prefix and separators

from compactref import generate_reference

reference = generate_reference(
    "01J2H8NQPG6B5X8KGN97SX3R5C",
    prefix="INC",
    separator="-",
)

print(reference)

Possible output:

INC-20260710-482731

Use a UUID

from uuid import uuid4

from compactref import generate_reference

internal_id = uuid4()
reference = generate_reference(internal_id)

Configure the suffix length

reference = generate_reference(
    "01J2H8NQPG6B5X8KGN97SX3R5C",
    suffix_length=8,
)

Possible output:

2026071048273164

Change the date format

The date_format argument accepts any datetime.strftime pattern. A finer-grained format also produces smaller collision buckets (see Choosing a suffix length).

reference = generate_reference(
    "01J2H8NQPG6B5X8KGN97SX3R5C",
    date_format="%Y%m%d-%H",
    separator="-",
    prefix="INC",
)

Possible output:

INC-20260710-14-482731

Use an integer or bytes identifier

from compactref import generate_reference

from_integer = generate_reference(123456789)
from_bytes = generate_reference(b"internal-record-123")

Deterministic generation

The same identifier, date and configuration produce the same reference:

from datetime import datetime

from compactref import generate_reference

generated_at = datetime(2026, 7, 10)

first = generate_reference(
    "01J2H8NQPG6B5X8KGN97SX3R5C",
    generated_at=generated_at,
)

second = generate_reference(
    "01J2H8NQPG6B5X8KGN97SX3R5C",
    generated_at=generated_at,
)

assert first == second

Supported source types

CompactRef accepts:

  • ULIDs represented as strings
  • UUID objects
  • strings
  • bytes
  • non-negative integers

Choosing a suffix length

A reference is unique only within a single bucket — references that share the same prefix and date part. Because the date resets each day, what matters is how many references you expect per bucket (for the default format, per day), not the all-time total.

Two helpers size the suffix using the birthday model.

Estimate the collision risk

collision_probability(reference_count, suffix_length) returns the probability that at least two references in one bucket share the same suffix:

from compactref import collision_probability

collision_probability(50, suffix_length=4)   # 0.1153  -> ~11.5%
collision_probability(50, suffix_length=6)   # 0.0012  -> ~0.1%
collision_probability(120, suffix_length=4)  # 0.5103  -> coin flip

Find a safe volume

max_references(suffix_length, max_probability=0.01) returns the largest number of references that keeps the risk at or below the threshold (1% by default):

from compactref import max_references

max_references(4)         # 14   -> under 1% risk with 4 digits
max_references(6)         # 142  -> under 1% risk with 6 digits
max_references(6, 0.05)   # 320  -> if you accept up to 5% risk

Pick a length for your volume

from compactref import collision_probability

expected_per_day = 200

for length in range(4, 9):
    risk = collision_probability(expected_per_day, suffix_length=length)
    print(f"{length} digits -> {risk:.3%}")

# 4 digits -> 86.330%
# 5 digits -> 18.045%
# 6 digits -> 1.970%
# 7 digits -> 0.199%
# 8 digits -> 0.020%

For roughly 200 references per day, a 7-digit suffix keeps the risk well under 1%.

Uniqueness warning

CompactRef does not replace the original internal identifier.

Shortening an identifier reduces the number of possible values. Different internal identifiers can produce the same compact reference.

Applications requiring unique references should:

  1. Keep the original ULID or UUID as the internal identifier.
  2. Add a unique constraint to the reference column.
  3. Detect and handle the unlikely possibility of a collision.
  4. Increase suffix_length when the expected volume requires it.

Requirements

Python 3.10 or newer.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

compactref-0.1.0.tar.gz (7.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

compactref-0.1.0-py3-none-any.whl (6.3 kB view details)

Uploaded Python 3

File details

Details for the file compactref-0.1.0.tar.gz.

File metadata

  • Download URL: compactref-0.1.0.tar.gz
  • Upload date:
  • Size: 7.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for compactref-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4b228211b31549abdd89f8a39bc471487ce5a206166e7bace5ebafb05ba7f6e0
MD5 4fa049e3cd1833e2c0b3459db2fb0ae0
BLAKE2b-256 24ff206cf6f0c48d8fc1dd5e4dc49ed421bf3c9d490db7f25798ef474f738517

See more details on using hashes here.

File details

Details for the file compactref-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: compactref-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for compactref-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 de364622959134d4cc28c503a1998f12816e6d59dfb03c370b3e49ff5c7d130f
MD5 cc3a0be5c6f58e5589438c5e6591715b
BLAKE2b-256 1c7176f310ac5f3aab50843b03af22a75e08b80427893f0328aab58e62c41311

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page