High-performance Python library for UUIDv47 operations - encoding UUIDv7 into UUIDv4 facades and decoding them back. Uses the same C implementation.
UUIDv47 is a technique for encoding UUIDv7 (time-ordered UUIDs) into UUIDv4 facades (random-looking UUIDs) using cryptographic keys. This allows you to:
- Hide temporal information in UUIDs while maintaining format compatibility
- Preserve randomness in the facade for security
- Maintain reversibility with the correct keys
- Ensure cross-language compatibility between implementations
import python_uuidv47 as uuidv47
# Set encryption keys once (use your own secure keys!)
uuidv47.set_keys(0x123456789ABCDEF0, 0xFEDCBA9876543210)
# Example with a UUIDv7 (time-ordered UUID)
original_uuid = "550e8400-e29b-71d4-a716-446655440000" # Version 7
# Encode to facade (looks like UUIDv4)
facade = uuidv47.encode(original_uuid)
print(f"Facade: {facade}") # e.g., "3ebd5dfc-1b0d-41d4-a716-446655440000"
# Decode back to original
decoded = uuidv47.decode(facade)
print(f"Decoded: {decoded}") # "550e8400-e29b-71d4-a716-446655440000"
assert original_uuid == decoded # Perfect roundtrip!
uv add python-uuidv47
Or with pip:
pip install python-uuidv47
git clone https://github.com/FatahChan/python-uuidv47.git
cd python-uuidv47
uv sync
Set the global encryption keys used for encoding and decoding operations.
Parameters:
k0
: First 64-bit encryption key (0 to 2^64-1)k1
: Second 64-bit encryption key (0 to 2^64-1)
Returns: True
if keys were set successfully
Example:
uuidv47.set_keys(0x123456789ABCDEF0, 0xFEDCBA9876543210)
Encode a UUIDv7 into a UUIDv4 facade using the global keys.
Parameters:
uuid_str
: A valid UUIDv7 string to encode
Returns: Encoded UUIDv4 facade string
Raises:
RuntimeError
: If keys are not setValueError
: If UUID format is invalid
Decode a UUIDv4 facade back to the original UUIDv7 using the global keys.
Parameters:
facade_str
: A valid UUID facade string to decode
Returns: Original UUIDv7 string
Raises:
RuntimeError
: If keys are not setValueError
: If facade format is invalid
Check if global encryption keys have been set.
Returns: True
if keys are set, False
otherwise
Validate if a string is a properly formatted UUID.
Parameters:
uuid_str
: String to validate
Returns: True
if valid UUID format, False
otherwise
This library is built for high-performance applications:
- Native C implementation using Cython for maximum speed
- Same algorithm as the Node.js node-uuidv47 package
- 100,000+ operations per second on modern hardware
- Minimal memory allocation and efficient string handling
- Thread-safe operations with nogil Cython blocks
import python_uuidv47 as uuidv47
import time
uuidv47.set_keys(0x123456789ABCDEF0, 0xFEDCBA9876543210)
test_uuid = "550e8400-e29b-71d4-a716-446655440000"
# Benchmark encoding
start = time.perf_counter()
for _ in range(100000):
facade = uuidv47.encode(test_uuid)
encode_time = time.perf_counter() - start
print(f"Encode: {100000/encode_time:.0f} ops/sec")
# Typical output: Encode: 150000+ ops/sec
This Python implementation produces identical results to the Node.js version:
# Python
uuidv47.set_keys(0x123456789ABCDEF0, 0xFEDCBA9876543210)
facade = uuidv47.encode("550e8400-e29b-71d4-a716-446655440000")
# Result: "3ebd5dfc-1b0d-41d4-a716-446655440000"
// Node.js (node-uuidv47)
const uuidv47 = require('node-uuidv47');
uuidv47.setKeys(0x123456789ABCDEF0n, 0xFEDCBA9876543210n);
const facade = uuidv47.encode("550e8400-e29b-71d4-a716-446655440000");
// Result: "3ebd5dfc-1b0d-41d4-a716-446655440000" (identical!)
- Use strong, random keys: Generate your encryption keys securely
- Keep keys secret: Never expose keys in logs, code, or public repositories
- Key rotation: Consider rotating keys periodically for enhanced security
- Constant-time operations: The implementation uses constant-time operations where possible
import secrets
# Generate secure random keys
k0 = secrets.randbits(64)
k1 = secrets.randbits(64)
uuidv47.set_keys(k0, k1)
The library provides clear error messages for common issues:
import python_uuidv47 as uuidv47
# Attempting operations without setting keys
try:
uuidv47.encode("550e8400-e29b-71d4-a716-446655440000")
except RuntimeError as e:
print(e) # "Keys not set. Call set_keys() first."
# Invalid UUID format
uuidv47.set_keys(123, 456)
try:
uuidv47.encode("invalid-uuid")
except ValueError as e:
print(e) # "Invalid UUIDv7 format"
- Python 3.9+
- uv (recommended) or pip
- Cython 3.0+
- C11 compatible compiler
git clone https://github.com/FatahChan/python-uuidv47.git
cd python-uuidv47
# Install development dependencies and build the package
uv sync --dev
# Run tests
uv run pytest tests/ -v
# Run benchmarks
uv run pytest tests/test_performance.py --benchmark-only
# Build source distribution
uv run python -m build --sdist
This project uses modern Python tooling:
- uv for fast Python package management
- Ruff for linting and formatting
- mypy for type checking
- pytest for testing with benchmarks
- pre-commit hooks for code quality
# Format code
uv run ruff format .
# Lint code
uv run ruff check .
# Type check
uv run mypy python_uuidv47/
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
MIT License - see LICENSE file for details.
- uuidv47 - Original uuid47 in C
- node-uuid47 uuid47 in Node.
See CHANGELOG.md for version history and changes.