python3 -m pip install ulid_tool --upgrade
Tool for Unique Lexicographically Identifier (ULID)
[Original title] Unique Lexicographically Sortable Identifier
ULID is a widely used specification for identifiers which, unlike UUID, aims for readability, anonymity, compatibility, and practical use through sortability. (Original specification: https://github.com/ulid/spec)
By modifying the original specification, this implementation enables the generation of guaranteed unique ULIDs within a file system.
The ULID specification does not achieve guaranteed cross-system uniqueness. Even the widely used UUID versions cannot achieve absolute uniqueness, even though they are considered unique in practice. This project deals with the highest possible uniqueness in time and space with the highest possible anonymity.
Statute
- This module implements the original specification and is extended by modifications that follow the idea and properties.
- The module contains utils as separate modules/functions/methods for the creation or handling of ULIDs.
- The module contains system integrity checks for the consistent creation of ULIDs.
- Python type checks during runtime are not performed.
Properties and basic concept
UUID vs ULID
Properties of a UUID
Depending on the version, a UUID can consist of
-
Timestamp
-
The Mac address
The use of a MAC address can be considered sensitive information about the creator that is being disclosed.
-
Random values
Random values can never be considered absolutely unique. Even though the probability of two identical UUIDv4s occurring is practically zero. Furthermore, random values naturally do not carry any information.
-
A centrally managed seed
A central, generally recognized authority is required.
Properties of a ULID
- 128-bit compatibility with UUID
- 1.21e+24 unique ULIDs per millisecond
- Lexicographically sortable
- Canonically encoded as a 26 character string, as opposed to the 36 character UUID
- Uses Crockford's base32 for better efficiency and readability (5 bits per character)
- Case insensitive
- No special characters (URL safe)
- Monotonic sort order (correctly detects and handles the same millisecond)
Binary Layout (original specification)
A ULID has a fixed length of 128 bits coded in 16 bytes/octets and consists of 2 components. Each component is coded in big-endian format (network byte order).
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
| | | | |
+---------------------------------------------------------------+
| ms since epoch |
+ - - - - - - - - - - - - - - - +-------------------------------+
| ... | randomnes |
+-------------------------------+ - - - - - - - - - - - - - - - +
| ... |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| ... |
+---------------------------------------------------------------+
Variations
ULID.runtime_lexical
Replaces the random part with a monotonic counter that counts up from 0 within a runtime and automatically restarts when the space is used up. Not thread-safe.
ULID.local_lexical
Similar to runtime_lexical. Reads the last status of the counter from the file system and writes the status when the Python interpreter terminates. Not thread-safe.
ULID.env_lexical
Here, the random part consists of 8 bits from a one-time read ID per interpreter start + 72 bits of a monotonic counter. Not sub-thread or sub-process safe. However, for up to 256 simultaneously running main processes.
ULID.thread_env_lexical
Structured like env_lexical. Here, the thread ID is used for system-wide uniqueness. Thread-safe.
ULID.short_env_lexical
Heavily modified version. The random part consists of only 8 bits. 4 bits from a uniquely read ID per interpreter start + 4 bits from a monotonic counter. Not sub-thread or sub-process safe. However, for up to 16 simultaneously running main processes.
Module usages
if bypass_checks:
# By default, several system integrity checks are performed during import.
# To bypass this, the following code can be used
import ulid_tool
ulid_tool.SYSTEM_CHECKS = False
from ulid_tool.ulid import ULID
else:
from ulid_tool.ulid import ULID
# ULID of ORIGINAL SPECIFICATION
ulid = ULID()
# VARIATIONS
ULID.runtime_lexical()
ULID.local_lexical()
ULID.env_lexical()
ULID.thread_env_lexical()
ULID.short_env_lexical()
# INTERFACES
## CONVERSIONS
ulid.bytes
ulid.int
ulid.str
ulid.codec
ulid.repr
ulid.hex
ulid.oct
ulid.bin
## PARTS
ulid.randomness
ulid.timestamp
ulid.prime
## CREATE FROM
ulid.from_interfaces(ulid.timestamp, ulid.randomness)
ulid.from_codec(ulid.codec)
ulid.from_bytes(ulid.bytes)
ulid.from_str(ulid.str)
ulid.from_int(ulid.int)
ulid.from_hex(ulid.hex)
ulid.from_oct(ulid.oct)
ulid.from_bin(ulid.bin)
ulid.from_repr(ulid.repr)
### UTIL
ulid.prime_from_type_of(ulid.oct)
## PROGRESSION
assert ulid.copy().this_forwards(n=1) == ulid.next
assert ulid.copy().this_backwards(n=1) == ulid.previous
ulid.igenerator(ni=3)
reversed(ulid.igenerator(ni=3))
Metadata
Release files for ulid-tool 5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ulid_tool-5.tar.gz | 17.4 kB | Without provenance | Details for ulid_tool-5.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ulid_tool-5-py3-none-any.whl | Python 3 | none | any | Details for ulid_tool-5-py3-none-any.whl |
Total release size: 32.0 kB
Release files / ulid_tool-5.tar.gz
| Download URL | ulid_tool-5.tar.gz |
|---|---|
| Size | 17.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
141caf30f366d2a344e4539ecbbd96a5b5a9183c194b3dae3822965ef0b4ef4c
|
|
BLAKE2b-256 checksum How to use checksums |
0bf0e44560256bf9405493f71fd9aed11ae992d341b9c9ff6b271cbdf8355844
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Release files / ulid_tool-5-py3-none-any.whl
| Download URL | ulid_tool-5-py3-none-any.whl |
|---|---|
| Size | 14.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
63936bc576c7dd3e9e405f0ce56cb4d02935ad1a061716ba96a591a893b01b25
|
|
BLAKE2b-256 checksum How to use checksums |
c7b42d7ac2b2aa7dce0f7682aa63be13375ee754288101ebe52d15488b17ea01
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Security for ulid-tool 5
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.