SeedHash is a library for generating deterministic random seeds from string inputs using MD5 hashing. Available in both Python and R, it's perfect for creating reproducible experiments, simulations, and any scenario where you need consistent random number generation across different runs.
seedhash/
βββ Python/ # Python implementation
β βββ seedhash/ # Python package
β βββ examples/ # Python examples
β βββ README.md # Python documentation
β
βββ R/ # R implementation
β βββ R/ # R package source
β βββ tests/ # R tests
β βββ examples/ # R examples
β βββ README.md # R documentation
β
βββ PYTHON_TO_R_GUIDE.md # Conversion guide for developers
βββ README.md # This file
- π― Deterministic: Same input string always produces the same sequence of random numbers
- π§ Configurable: Customize the range of generated random numbers
- β Type-Safe: Comprehensive error handling and input validation
- π¦ Lightweight: Minimal dependencies (Python: none, R: R6 + digest)
- π Easy to Use: Simple, intuitive API
- π Cross-Language: Available in both Python and R
- π² 4 Sampling Methods: Simple, Stratified, Cluster, and Systematic random sampling
- π§ͺ ML Integration: Experiment tracking with hierarchical seed management
- π₯οΈ Multi-GPU Ready: Seeds PyTorch the same way on one GPU, several GPUs, or several nodes (torchrun, SLURM, MPI)
# From GitHub
pip install git+https://github.com/melhzy/seedhash.git#subdirectory=Python
# From local directory
cd Python
pip install .See Python/README.md for detailed instructions.
# Recommended: Using pak
install.packages("pak", repos = "https://r-lib.github.io/p/pak/stable/")
pak::pkg_install("github::melhzy/seedhash/R")
# Alternative: Using devtools
devtools::install_github("melhzy/seedhash", subdir = "R")See R/INSTALL.md for detailed instructions.
from seedhash import SeedHashGenerator
# Create a generator with an input string
generator = SeedHashGenerator("my_experiment_name")
# Generate 10 random seeds
seeds = generator.generate_seeds(10)
print(seeds)
# Get the MD5 hash
print(generator.get_hash())library(seedhash)
# Create a generator
generator <- SeedHashGenerator$new("my_experiment_name")
# Generate 10 random seeds
seeds <- generator$generate_seeds(10)
print(seeds)
# Get the MD5 hash
cat(generator$get_hash(), "\n")from seedhash import SeedHashGenerator
# Initialize with a string
gen = SeedHashGenerator("Shalini")
# Generate 10 random seeds (default range: 0 to 2^31-1)
random_seeds = gen.generate_seeds(10)
print(f"Generated seeds: {random_seeds}")
# Get the underlying hash
print(f"MD5 Hash: {gen.get_hash()}")
print(f"Seed number: {gen.seed_number}")from seedhash import SeedHashGenerator
# Custom range for random numbers
gen = SeedHashGenerator(
input_string="experiment_42",
min_value=100,
max_value=1000
)
# Generate 5 seeds in the range [100, 1000]
seeds = gen.generate_seeds(5)
print(f"Seeds in range [100, 1000]: {seeds}")from seedhash import SeedHashGenerator
# The library includes comprehensive error checking
try:
# Empty string raises ValueError
gen = SeedHashGenerator("")
except ValueError as e:
print(f"Error: {e}")
try:
# Invalid range raises ValueError
gen = SeedHashGenerator("test", min_value=100, max_value=50)
except ValueError as e:
print(f"Error: {e}")
try:
# Non-positive count raises ValueError
gen = SeedHashGenerator("test")
seeds = gen.generate_seeds(0)
except ValueError as e:
print(f"Error: {e}")from seedhash import SeedHashGenerator
# Same input always produces same output
gen1 = SeedHashGenerator("experiment_1")
seeds1 = gen1.generate_seeds(5)
gen2 = SeedHashGenerator("experiment_1")
seeds2 = gen2.generate_seeds(5)
assert seeds1 == seeds2 # Always True!
print(f"Reproducible: {seeds1} == {seeds2}")SeedHashGenerator(input_string, min_value=None, max_value=None)Parameters:
input_string(str): The string to hash for seed generationmin_value(int, optional): Minimum value for random number range. Default: 0max_value(int, optional): Maximum value for random number range. Default: 2^31 - 1
Raises:
TypeError: Ifinput_stringis not a string or range values are not integersValueError: Ifinput_stringis empty ormin_value >= max_value
Generate a list of random seed numbers.
Parameters:
count(int): The number of random seeds to generate
Returns:
List[int]: A list of random integers within the specified range
Raises:
TypeError: If count is not an integerValueError: If count is not positive
Get the MD5 hash of the input string.
Returns:
str: The MD5 hash as a hexadecimal string
input_string(str): The input string used for seed generationmin_value(int): Minimum value for random numbersmax_value(int): Maximum value for random numbersseed_number(int): The integer seed derived from the input string
from seedhash import SeedHashGenerator
# Reproducible train/test splits
experiment_name = "model_v1_baseline"
gen = SeedHashGenerator(experiment_name)
seeds = gen.generate_seeds(5) # For different folds
for i, seed in enumerate(seeds):
print(f"Fold {i+1} seed: {seed}")
# Use seed for train_test_split, model initialization, etc.from seedhash import SeedHashGenerator
# Reproducible simulation runs
simulation_id = "monte_carlo_sim_2025"
gen = SeedHashGenerator(simulation_id, min_value=1, max_value=10000)
# Generate seeds for parallel simulation runs
num_simulations = 100
simulation_seeds = gen.generate_seeds(num_simulations)from seedhash import SeedHashGenerator
import random
# Reproducible data sampling
dataset_version = "dataset_v2.1"
gen = SeedHashGenerator(dataset_version)
sample_seed = gen.generate_seeds(1)[0]
random.seed(sample_seed)SeedHash includes 4 scientifically-backed sampling methods for systematic seed generation:
from seedhash import SeedSampler
sampler = SeedSampler(master_seed=42)
# 1. Simple Random Sampling - Pure randomness
simple = sampler.simple_random_sampling(n_samples=10, seed_range=(0, 1000))
# 2. Stratified Random Sampling - Balanced coverage
stratified = sampler.stratified_random_sampling(
n_samples=25, seed_range=(0, 1000), n_strata=5
)
# 3. Cluster Random Sampling - Grouped seeds
cluster = sampler.cluster_random_sampling(
n_samples=20, seed_range=(0, 1000), n_clusters=4
)
# 4. Systematic Random Sampling - Even intervals
systematic = sampler.systematic_random_sampling(n_samples=15, seed_range=(0, 1000))π Full Sampling Methods Documentation β
from seedhash import SeedExperimentManager
import numpy as np
# Create experiment manager
manager = SeedExperimentManager("my_ml_project")
# Generate hierarchical seeds: master β seeds β sub-seeds
hierarchy = manager.generate_seed_hierarchy(
n_seeds=10,
n_sub_seeds=5,
max_depth=2,
sampling_method="stratified" # Use any of the 4 methods
)
# Track experiments
for seed in hierarchy[1]:
# Run your experiment
np.random.seed(seed)
accuracy = 0.8 + np.random.rand() * 0.15
# Record results
manager.add_experiment_result(
seed=seed,
ml_task="classification",
metrics={"accuracy": accuracy, "f1_score": 0.85},
sampling_method="stratified"
)
# Export to DataFrame
df = manager.get_results_dataframe()
df.to_csv('experiment_results.csv')π Full Documentation | π Jupyter Tutorials
Python/
βββ seedhash/
β βββ __init__.py # Package initialization
β βββ core.py # Core SeedHashGenerator class
β βββ experiment.py # Experiment tracking
βββ examples/
β βββ demo.py # Usage examples
β βββ hierarchical_sampling.py
β βββ deep_learning_seeding.py
β βββ distributed_seeding.py # Multi-GPU / multi-node
β βββ advanced_ml_paradigms.py
βββ setup.py # Setup configuration
βββ pyproject.toml # Modern Python packaging
βββ requirements.txt # Dependencies
βββ README.md # Python documentation
R/
βββ R/
β βββ seedhash.R # R package implementation
βββ man/ # R documentation
βββ tests/
β βββ testthat.R # testthat entry point
β βββ testthat/
β βββ test-seedhash.R # R tests
βββ examples/
β βββ example_usage.R
βββ DESCRIPTION # R package metadata
βββ README.md # R documentation
Root files:
βββ paper.md # JOSS paper
βββ paper.bib # References
βββ CONTRIBUTING.md # Contribution guidelines
βββ CODE_OF_CONDUCT.md # Code of conduct
βββ LICENSE # MIT License
βββ README.md # This file
# Python: install in development mode, then run the tests from the repository root
pip install -e "Python[experiment]" pytest
pytest test_*.py -v
# R: install the package, then run its testthat suite
R CMD INSTALL R
Rscript -e 'testthat::test_dir("R/tests/testthat", package = "seedhash", load_package = "installed")'# Install build tools
pip install build
# Build the package
python -m build
# This creates dist/seedhash-0.1.0.tar.gz and dist/seedhash-0.1.0-whl# Install twine
pip install twine
# Upload to PyPI
twine upload dist/*We welcome contributions from the community! Please see our Contributing Guidelines for details on:
- Reporting bugs and suggesting enhancements
- Development setup for Python and R
- Coding standards and testing requirements
- Pull request process
Please also read our Code of Conduct before contributing.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Make your changes following our coding standards
- Add tests for new functionality
- Ensure all tests pass
- Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
For questions, please open an issue on GitHub.
This project is licensed under the MIT License - see the LICENSE file for details.
Ziyuan Huang
- ORCID: 0000-0002-2215-2473
- Affiliation: University of Massachusetts Chan Medical School
- GitHub: @melhzy
If you use SeedHash in your research or project, please consider citing it:
@software{huang2025seedhash,
author = {Ziyuan Huang},
title = {{SeedHash}: {MD5}-Based Deterministic Random Seed Generator},
year = {2025},
month = oct,
publisher = {Zenodo},
version = {0.1.0},
doi = {10.5281/zenodo.17495331},
url = {https://github.com/melhzy/seedhash}
}Huang, Z. (2025). SeedHash: MD5-based deterministic random seed generator
(Version 0.1.0) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.17495331
Huang, Ziyuan. 2025. "SeedHash: MD5-Based Deterministic Random Seed Generator."
Version 0.1.0. Zenodo. https://doi.org/10.5281/zenodo.17495331.
- Initial release
- Core
SeedHashGeneratorclass - MD5-based seed generation
- Configurable random number ranges
- Comprehensive error handling
- Full documentation and examples
- Inspired by the need for reproducible random number generation in scientific computing
- Built with Python's standard library for maximum compatibility
- Rivest, R. (1992). The MD5 Message-Digest Algorithm (RFC 1321). MIT Laboratory for Computer Science and RSA Data Security, Inc. https://datatracker.ietf.org/doc/html/rfc1321
- Python Software Foundation. (2024). random β Generate pseudo-random numbers. In Python Standard Library (Python 3.x documentation). https://docs.python.org/3/library/random.html
Note: This library uses MD5 hashing for seed generation. MD5 is suitable for non-cryptographic purposes like seed generation. Do not use this library for cryptographic or security-sensitive applications.