small/id

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

pkg:composer/small/id

1.0.0 2025-10-04 19:59 UTC

This package is not auto-updated.

Last update: 2025-10-05 18:09:37 UTC


README

   

Multi‑strategy Unique ID generators (UUIDv1/v3/v4/v5/v6/v7, ULID, KSUID, Snowflake, ObjectId, NanoID)

A tiny PHP library that provides a uniform interface to generate a variety of unique identifiers: UUID (v1/3/4/5/6/7), ULID, KSUID, Snowflake, ObjectId, and NanoID — via a simple IdInterface and a factory.

Uses PHP’s random_bytes() / random_int() (CSPRNG) where applicable.
UUIDv7 is time‑ordered (great for DB indexes).
v3/v5 are deterministic (same namespace+name ⇒ same UUID).
⚠️ UUIDv2 (DCE) is not implemented and throws a LogicException by design.

Requirements

  • PHP 8.3+
  • No extensions required beyond standard PHP (ext‑hash for SHA‑1/MD5 which is part of core).
  • No composer dependency

Installation

As a Composer package (recommended)

If you publish this as small/id on Packagist:

composer require small/id

Quick start

use Small\Id\IdFactory;
use Small\Id\Enum\IdType;

$factory = new IdFactory();

$uuid7 = $factory->getId(IdType::uuid_v7)->generate();   // e.g. "018fb27a-a2b1-7c3d-8e9f-1a2b3c4d5e6f"
$ulid  = $factory->getId(IdType::ulid)->generate();      // e.g. "01J234ABCD3EFG4567HJKMNPRT"
$ksuid = $factory->getId(IdType::ksuid)->generate();     // base62 string (~27 chars)
$snow  = $factory->getId(IdType::snowflacke)->generate();// decimal string (64‑bit composed)
$oid   = $factory->getId(IdType::objectid)->generate();  // 24‑hex Mongo‑like
$nano  = $factory->getId(IdType::nanoid)->generate();    // 21 chars URL‑safe

Supported algorithms

UUID family (128‑bit, canonical 8-4-4-4-12 hex with variant bits)

  • UUidV1 — time‑based (no MAC leakage: random node).
    Ordered. Good locality. Not deterministic.

  • UUidV3 — name‑based MD5 (deterministic).
    In this library, a default namespace+name is used; you can extend the class to inject custom values.

  • UUidV4 — random (122 random bits).
    Not ordered; best for general randomness.

  • UUidV5 — name‑based SHA‑1 (deterministic).
    Same behavior note as v3.

  • UUidV6 — reordered Gregorian time (lexicographically sortable).
    Ordered by creation time; no MAC leakage.

  • UUidV7 — Unix time (ms) + randomness (ordered).
    Includes a small monotonic sequence to keep order within the same millisecond.

  • UUidV2 — DCE Security (POSIX). Not implemented; calling generate() throws LogicException to avoid silent misuse.

Usage examples

use Small\Id\IdFactory;
use Small\Id\Enum\IdType;

$factory = new IdFactory();

// UUIDv7 for ordered DB primary keys
$uuid7 = $factory->getId(IdType::uuid_v7)->generate();

// Deterministic UUIDv5 (as shipped: constant ns+name)
$uuid5 = $factory->getId(IdType::uuid_v5)->generate();

// Human‑friendlier, sortable ID
$ulid = $factory->getId(IdType::ulid)->generate();

// Compact bigint‑like numeric ID
$snowflake = $factory->getId(IdType::snowflacke)->generate();

Testing (Pest)

Install and init:

composer require pestphp/pest --dev
vendor/bin/pest --init

Run the suite:

vendor/bin/pest

What the tests cover:

  • Correct textual formats for each generator
  • Uniqueness across successive generations (except v3/v5 which are deterministic)
  • UUIDv2 explicitly throws LogicException
  • Basic length checks (ULID 26, NanoID 21, KSUID ~27, ObjectId 24‑hex, etc.)

If you want stress tests (e.g., 10k UUIDv7 under a tight loop to verify monotonicity and absence of collisions), add a separate stress group to keep your CI fast.

Notes & guarantees

  • CSPRNG: random_bytes() / random_int() are used wherever randomness is required.
  • Monotonicity:
    • UUidV7 includes a 12‑bit sequence; it increments within the same millisecond and spins to the next ms if the sequence overflows.
    • Snowflake uses a 12‑bit per‑ms counter and spins to next ms on overflow.
  • Determinism:
    • UUidV3 / UUidV5 are deterministic for the internal namespace + name. Extend these classes to inject your own namespace+name if needed.
  • Privacy:
    • UUidV1 uses a random node with the multicast bit set (no MAC leakage).
  • UUIDv2:
    • Not implemented (rare, POSIX‑specific). The class throws by design so you don’t accidentally rely on an incomplete implementation.

License

Copyright 2025 - Sébastien Kus
Under MIT License