ids_service 2.0.1

Library that allows to generate unique Ids.
Documentation
ids_service-2.0.1 has been yanked.

Licence Version dependency status Download pipeline docs.rs

ids_service

A Rust library for generating unique, cryptographically-sound IDs using a pre-filled, multi-threaded cache. Background worker threads keep the cache full so that callers receive a pre-computed ID instantly without blocking.

If the cache is temporarily exhausted (burst traffic), an ID is generated on the fly — no error, no panic, just a small latency spike.


How it works

  ┌──────────────────────────────────────────────────────┐
  │                    IdsService                        │
  │                                                      │
  │  ┌──────────┐   push    ┌─────────────────────────┐ │
  │  │ Worker 0 │ ────────► │                         │ │
  │  ├──────────┤           │  Arc<Mutex<VecDeque>>   │ │  get_id()
  │  │ Worker 1 │ ────────► │       (cache)           │ ├──────────► caller
  │  ├──────────┤           │                         │ │
  │  │ Worker N │ ────────► │  size = cache_size      │ │
  │  └──────────┘           └─────────────────────────┘ │
  │                                                      │
  │  Each ID = hash( random_bytes || timestamp_ns )      │
  └──────────────────────────────────────────────────────┘

Each ID is derived from:

  • A random byte block (size = 2 × hash output length — see Birthday problem)
  • The current timestamp in nanoseconds since the Unix epoch

Modules

crypto_hash

Uses one of the SHA-3 family algorithms from the sha3 crate:

Mode Output Random block
Sha3Mode::Sha3_224 28 bytes 56 bytes
Sha3Mode::Sha3_256 32 bytes 64 bytes
Sha3Mode::Sha3_384 48 bytes 96 bytes
Sha3Mode::Sha3_512 64 bytes 128 bytes

IDs can be encoded as:

Method Output
.as_hex() Lowercase hexadecimal String
.as_base64() Standard Base64 String
.as_base64_url() URL-safe Base64 String
.as_base32() Base32 String
.as_json() JSON array of byte values

rust_hash

Uses std::collections::hash_map::DefaultHasher (SipHash 1-3). IDs are u64 values. Faster than crypto_hash, but not cryptographically secure — suitable for non-security-sensitive use cases.


Feature flags

Flag Default Description
all Enables both crypto and rust
crypto Enables crypto_hash module (requires sha3 dep)
rust Enables rust_hash module

To use only one module, disable default features in Cargo.toml:

# Only the rust hasher — no sha3 dependency
ids_service = { version = "2.0.1", default-features = false, features = ["rust"] }

# Only the crypto hasher
ids_service = { version = "2.0.1", default-features = false, features = ["crypto"] }

Quick Start

Cryptographic hash (crypto_hash)

use ids_service::crypto_hash::{IdsService, Sha3Mode};
use ids_service::common::{Encode, Service, Uids};

fn main() {
    // Cache size = 100 000, SHA3-256, thread count = number of logical CPUs
    let mut ids = IdsService::new(100_000, Sha3Mode::Sha3_256, None);
    ids.start();

    // Optional: block until the cache is at least 10 % full
    let _ = ids.filled_at_percent_event(10).recv();

    println!("hex:    {}", ids.get_id().as_hex());
    println!("base64: {}", ids.get_id().as_base64());
    println!("base32: {}", ids.get_id().as_base32());

    // Returns None when the cache is empty instead of generating on the fly
    if let Some(id) = ids.get_id_from_cache() {
        println!("from cache: {}", id.as_hex());
    }

    println!("cache len: {}", ids.get_cache_len());

    // Graceful shutdown — joins worker threads
    ids.stop();
}

Or use the default configuration (SHA3-256, 100 000 items, CPU-count threads):

use ids_service::crypto_hash::IdsService;
use ids_service::common::{Encode, Service, Uids};

fn main() {
    let mut ids = IdsService::default();
    ids.start();
    let _ = ids.filled_event().recv(); // wait for full cache
    println!("{}", ids.get_id().as_hex());
    ids.stop();
}

Iterator interface

IdsService implements Iterator, yielding one ID per call:

use ids_service::crypto_hash::{IdsService, Sha3Mode};
use ids_service::common::{Encode, Service};

fn main() {
    let mut ids = IdsService::new(10_000, Sha3Mode::Sha3_512, None);
    ids.start();

    for id in ids.by_ref().take(5) {
        println!("{}", id.as_hex());
    }

    ids.stop();
}

Standalone (no service, no cache)

use ids_service::crypto_hash::{create_id_as_sha256, create_id_as_sha512};

fn main() {
    println!("{}", create_id_as_sha256()); // hex-encoded SHA3-256
    println!("{}", create_id_as_sha512()); // hex-encoded SHA3-512
}

Rust hasher (rust_hash)

use ids_service::rust_hash::IdsService;
use ids_service::common::{Service, Uids};

fn main() {
    // Cache size = 200 000, thread count = number of logical CPUs
    let mut ids = IdsService::new(200_000, None);
    ids.start();

    let _ = ids.filled_at_percent_event(10).recv();

    println!("id:         {}", ids.get_id());
    println!("from cache: {}", ids.get_id_from_cache().expect("cache non-empty"));
    println!("cache len:  {}", ids.get_cache_len());

    ids.stop();
}

Standalone (no service, no cache)

use ids_service::rust_hash::create_id;

fn main() {
    println!("{}", create_id()); // u64
}

Performance

Benchmarks run with Criterion.rs on an AMD Ryzen AI 7 350cargo bench.

Results

Benchmark Time Throughput
crypto_hash/standalone/sha256 ~830 ns ~1.2 Melem/s
crypto_hash/standalone/sha512 ~845 ns ~1.2 Melem/s
crypto_hash/service/get_id/Sha3_256 ~105–127 ns ~7.9–9.5 Melem/s
crypto_hash/service/get_id/Sha3_512 ~75–92 ns ~10.8–13.4 Melem/s
rust_hash/standalone/create_id ~830 ns ~1.2 Melem/s
rust_hash/service/get_id ~101–150 ns ~6.6–9.9 Melem/s

Cache hit = Mutex::lock + VecDeque::pop_front ≈ 75–150 ns — 7–10× faster than standalone generation.

Run the full benchmark suite:

cargo bench --bench throughput

Results are saved as HTML reports in target/criterion/.


Examples

# Cryptographic hasher examples
cargo run --example quickstart
cargo run --example quickstart2
cargo run --example examples
cargo run --example iterator_example

# Rust hasher examples
cargo run --example quickstart_rh
cargo run --example quickstart2_rh
cargo run --example examples_rh
cargo run --example iterator_example_rh

# Generate 10 million IDs and measure throughput
cargo run --release --example ten_million
cargo run --release --example ten_million_rh

Running tests

# All unit and doc tests
cargo test

# With a specific feature set
cargo test --no-default-features --features crypto
cargo test --no-default-features --features rust

Platforms

Compiled and tested on:

  1. x86_64 GNU/Linux (primary development + CI)
  2. macOS (Apple Silicon M1)

License

MIT — see LICENSE.