Skip to main content

Deterministic & secure random generation toolkit — reproducible PRNG for simulation/testing and CSPRNG for security-sensitive material.

Project description

ouroboros_random

A professional, zero-dependency, production-ready random generation toolkit for Python.
Designed for deterministic simulation, reproducible testing, temporal traffic synthesis, and security-grade entropy — all in a single, auditable library.

ouroboros_random provides two complementary classes with a strict separation of concerns:

Class Engine Purpose
BaseRandom Mersenne Twister (MT19937) seeded PRNG Simulation, testing, benchmarking, statistical analysis
BaseEntropy OS CSPRNG via secrets Tokens, keys, UUIDs, session IDs, secure bytes

Why two classes?
Mixing reproducible PRNG output with security-sensitive material is a common source of bugs.
This separation makes code review trivial: BaseRandom = simulation; BaseEntropy = security.


Table of Contents

  1. Features
  2. Installation
  3. Python Compatibility
  4. Usage Examples
  5. Architecture
  6. Design Principles
  7. Testing
  8. Development Dependencies
  9. Security Considerations
  10. License

Features

BaseRandom — Deterministic Generator

  • Full reproducibility — same seed + same call sequence = identical output, cross-platform
  • State snapshotssnapshot() / restore() and Base64 serialization for replay
  • Core primitivesrandom(), randint(), uniform(), gauss(), choice(), choices()
  • Weighted & unweighted selectionweighted_choice(), sample() (without replacement), shuffle()
  • Typed generatorsint, long, float, double, byte, bytes, boolean, date, time, datetime, epoch_millis
  • Geo generatorslatitude, longitude, geopoint
  • Identifiers & stringsdeterministic_hex_id, generate_string, generate_base64_string, generate_base64_utf8_text
  • Network generatorsIPv4, IPv6, MAC address, hostname (all deterministic, no OS entropy)
  • Enum supportgenerate_enum() picks a deterministic member from any enum.Enum subclass
  • Temporal distributions (streaming)stream_uniform, stream_poisson, stream_gaussian, stream_exponential, stream_burst
  • Dependency-free Poisson — exact Knuth algorithm + normal approximation fallback, no NumPy required

BaseEntropy — Secure Generator

  • UUIDv4secure_uuid()
  • Tokenssecure_token_urlsafe(), secure_token_hex()
  • Bytessecure_bytes()
  • Integerssecure_int(a, b) via rejection sampling
  • Stringssecure_string() with custom alphabets
  • Networksecure_ipv4(), secure_ipv6(), secure_mac()

Typed Exception Hierarchy

All exceptions inherit from RandomToolkitError for clean except handling:

RandomToolkitError
├── InvalidParameterError
├── EmptyPopulationError
├── InsufficientPopulationError
├── StateRestorationError
└── GenerationError

Installation

Local (development)

pip install -e .

From Git repository

pip install git+https://your.git.server/ouroboros_random.git

Inside CI/CD (Docker / Jenkins)

pip install git+https://your.git.server/ouroboros_random.git

Python Compatibility

Python 3.9 - 3.13

Zero runtime dependencies. The entire library uses only the Python standard library.


Usage Examples

Basic deterministic generation

from ouroboros_random import BaseRandom

rng = BaseRandom(seed=42)

rng.generate_int(0, 100)          # deterministic integer
rng.generate_float(0.0, 1.0)      # deterministic float
rng.generate_boolean(p_true=0.7)  # biased coin flip
rng.generate_string(16)           # alphanumeric string
rng.generate_ipv4(kind="private") # RFC1918 address
rng.generate_geopoint()           # (lat, lon) tuple
rng.deterministic_hex_id(32)      # hex identifier

Weighted selection

from ouroboros_random import BaseRandom

rng = BaseRandom(seed=99)

items = ["critical", "warning", "info", "debug"]
weights = [1.0, 5.0, 20.0, 74.0]

rng.weighted_choice(items, weights)  # probabilistic but deterministic

Sampling without replacement

rng.sample(["A", "B", "C", "D", "E"], k=3)  # 3 unique elements
rng.shuffle([1, 2, 3, 4, 5])                  # new shuffled list (original untouched)

Enum support

import enum
from ouroboros_random import BaseRandom

class Color(enum.Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

rng = BaseRandom(seed=7)
rng.generate_enum(Color)  # deterministic Color member

State snapshots for replay

from ouroboros_random import BaseRandom

rng = BaseRandom(seed=42)
snap = rng.snapshot()

a = [rng.randint(0, 100) for _ in range(10)]

rng.restore(snap)
b = [rng.randint(0, 100) for _ in range(10)]

assert a == b  # identical sequences

Base64 snapshot (portable)

encoded = rng.snapshot_b64()
# ... persist / transmit ...
rng.restore_b64(encoded)

Secure generation (tokens, keys)

from ouroboros_random import BaseEntropy

BaseEntropy.secure_uuid()                # UUIDv4
BaseEntropy.secure_token_urlsafe(32)     # URL-safe token
BaseEntropy.secure_token_hex(32)         # hex token
BaseEntropy.secure_bytes(64)             # raw bytes
BaseEntropy.secure_int(1, 1_000_000)     # secure integer
BaseEntropy.secure_string(24)            # random string
BaseEntropy.secure_ipv4(kind="global")   # secure public IPv4
BaseEntropy.secure_mac(uppercase=True)   # secure MAC address

Temporal traffic synthesis

from datetime import datetime
from ouroboros_random import BaseRandom

rng = BaseRandom(seed=1)

# 7-day window, 5-minute granularity
intervals = BaseRandom.generate_intervals(
    period_days=7,
    granularity_minutes=5,
    now=datetime(2026, 1, 1),
)

# Uniform distribution: 10k events
timestamps = list(rng.stream_uniform(intervals, 10_000, jitter_ms=60_000))

# Poisson distribution: ~3 events per bin
timestamps = list(rng.stream_poisson(intervals, mean_per_interval=3.0))

# Gaussian-shaped: peak at center
timestamps = list(rng.stream_gaussian(intervals, 10_000))

# Exponential decay: front-loaded
timestamps = list(rng.stream_exponential(intervals, 10_000, scale=0.5))

# Burst: 80% of events in a narrow spike
timestamps = list(rng.stream_burst(intervals, 10_000, burst_ratio=0.8, burst_width=0.05))

Architecture

ouroboros_random/
├── __init__.py       # Public API surface & __all__
├── base.py           # Backward-compatible re-export module
├── _types.py         # Type aliases (Millis) and type variables
├── _config.py        # PoissonPolicy configuration dataclass
├── _state.py         # PRNG state management mixin (snapshot / restore)
├── _core.py          # Core PRNG primitives mixin (random, choice, sample, ...)
├── _generators.py    # Typed generators mixin (int, float, bool, date, geo, enum)
├── _strings.py       # String & identifier generators mixin (hex, base64, ...)
├── _network.py       # Network generators mixin (IPv4, IPv6, MAC, hostname)
├── _temporal.py      # Temporal distributions mixin (stream_*, Poisson, intervals)
├── _prng.py          # BaseRandom — composes all mixins into a single class
├── _entropy.py       # BaseEntropy — CSPRNG-backed secure generator
├── exceptions.py     # Typed exception hierarchy
├── py.typed          # PEP 561 marker for type checkers
tests/
├── conftest.py       # Shared fixtures (seeded BaseRandom)
├── test_core.py      # Core primitives & selection tests
├── test_state.py     # State snapshot & restore tests
├── test_generators.py# Typed generators tests
├── test_strings.py   # String & identifier tests
├── test_network.py   # Network address generation tests
├── test_temporal.py  # Temporal distribution & Poisson tests
├── test_entropy.py   # BaseEntropy (secure) tests
├── test_exceptions.py# Exception hierarchy tests
└── test_backward_compat.py  # Import compatibility tests

Design Principles

  1. Zero dependencies — stdlib only; no NumPy, no SciPy, no external C extensions.
  2. Strict PRNG/CSPRNG separation — impossible to accidentally use a non-secure generator for secrets.
  3. Full reproducibility — seed to deterministic output. State snapshots for checkpoint/replay.
  4. Mixin-based architecture — each domain (core, generators, network, temporal, strings, state) lives in its own module with a focused mixin class, composed into BaseRandom via multiple inheritance.
  5. Streaming architecture — temporal distributions yield timestamps lazily (Iterator), enabling memory-efficient processing of millions of events.
  6. Typed exceptions — catch RandomToolkitError for the entire family, or discriminate specific failure modes.
  7. Backward compatibilitybase.py re-exports all symbols so existing from ouroboros_random.base import ... code keeps working.
  8. Python 3.9+ compatibility — uses from __future__ import annotations and typing aliases for broad support.

Testing

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest -v

# With coverage
pytest --cov=ouroboros_random --cov-report=term-missing

# Type checking
mypy ouroboros_random/

Development Dependencies

pytest >= 7.0
pytest-cov
ruff
mypy

Security Considerations

Aspect BaseRandom BaseEntropy
Engine MT19937 (not crypto-safe) OS CSPRNG (secrets)
Predictability Yes — 624 outputs allow full state recovery No — computationally infeasible
Use for tokens/keys Never Designed for this
Reproducibility Full (seed-based) Not applicable (by design)
State serialization snapshot_b64() — uses pickle (trusted sources only) N/A

pickle warning: restore_b64() deserializes with pickle. Never restore snapshots from untrusted sources.


License

This project is licensed under the MIT License - see the LICENSE file for details.


Authors

Flavio Brandolini

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

ouroboros_random-1.0.0.tar.gz (33.4 kB view details)

Uploaded Source

Built Distribution

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

ouroboros_random-1.0.0-py3-none-any.whl (27.9 kB view details)

Uploaded Python 3

File details

Details for the file ouroboros_random-1.0.0.tar.gz.

File metadata

  • Download URL: ouroboros_random-1.0.0.tar.gz
  • Upload date:
  • Size: 33.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ouroboros_random-1.0.0.tar.gz
Algorithm Hash digest
SHA256 d9f55930761b6e55c3cb6ac11512674b79a5bcb6607eba065e98da0f23822d2d
MD5 13f0bb3cd37abd2cfe519a8237c61a90
BLAKE2b-256 8d0a3c053c14ebc1258dd838cb8cd3d3bd51b76e300bb265df70d15bbb6f4269

See more details on using hashes here.

File details

Details for the file ouroboros_random-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: ouroboros_random-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 27.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ouroboros_random-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5d4fd365e47b2c7b5c74da1ce4c6376afbf6dce7130e6bd34de5b038ccff4335
MD5 2a0c15a280007d81b56462dfabbe758e
BLAKE2b-256 2482cb8a6713c6776ddb2928f0cfde6547424d3f8e73ca0ed8b4ac0a385ca885

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