PHPackages                             inanepain/id-forge - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. inanepain/id-forge

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

inanepain/id-forge
==================

A lightweight &amp; versatile library for generating and encoding unique identifiers. It provides fast, secure, and flexible solutions for modern applications.

0.1.0(6mo ago)10UnlicensePHPPHP &gt;=8.4

Since Oct 28Pushed 1mo agoCompare

[ Source](https://github.com/inanepain/id-forge)[ Packagist](https://packagist.org/packages/inanepain/id-forge)[ Docs](https://git.cathedral.co.za:3000/inanepain/id-forge)[ RSS](/packages/inanepain-id-forge/feed)WikiDiscussions develop Synced 1mo ago

READMEChangelogDependencies (1)Versions (3)Used By (0)

inanepain/id-forge [![icon](./icon.png "inanepain/id-forge")](./icon.png)
=========================================================================

[](#inanepainid-forge-)

Table of Contents

- [![icon](./icon.png "inanepain/id-forge") inanepain/id-forge](#inanepainid-forge)
- [Install](#install)
- [Quickstart](#quickstart)
- [Modules](#modules)
- [Encoders](#encoders)
    - [.1. Contracts and base classes](#contracts-and-base-classes)
    - [.2. Implementations](#implementations)
    - [.3. Configuration](#configuration)
    - [.4. Exceptions](#exceptions)
    - [.5. See also](#see-also)
- [1. Generators](#generators)
    - [1.1. Contract and base class](#contract-and-base-class)
    - [1.2. Implementations](#implementations-1)
    - [1.3. See also](#see-also-1)
- [2. Configuration](#configuration-1)
    - [2.1. EncoderConfig](#encoderconfig)
    - [2.2. SnowflakeConfig](#snowflakeconfig)
    - [2.3. See also](#see-also-2)
- [3. Factories](#factories)
    - [3.1. EncoderFactory](#encoderfactory)
    - [3.2. IdGeneratorFactory](#idgeneratorfactory)
    - [3.3. See also](#see-also-3)
- [4. Example](#example)
- [5. Error handling](#error-handling)
- [6. When to use which generator](#when-to-use-which-generator)

[![icon](./icon.png "inanepain/id-forge")](./icon.png) inanepain/id-forge
-------------------------------------------------------------------------

[](#-inanepainid-forge)

A lightweight &amp; versatile library for generating and encoding unique identifiers. It provides fast, secure, and flexible solutions for modern applications.

- Reversible encoders (`Base32`, `Base58`, `Base64`) via a common `EncoderInterface`
- Several ID generators (`UUIDv4`, `ULID`, `Nanoid`, Snowflake-like IDs) via a common `IdGeneratorInterface`
- Simple configuration of objects and factory helpers

Tip

All examples target PHP 8.2+ (the codebase is PHP 8.4-ready). Namespaces are rooted under `Inane\IdForge`.

Install
-------

[](#install)

composer

```
composer require inanepain/id-forge
```

Quickstart
----------

[](#quickstart)

Generate a few IDs

```
use Inane\IdForge\IdGeneratorFactory;
use Inane\IdForge\EncoderFactory;

$uuid    = IdGeneratorFactory::createUUID()->generate();
$ulid    = IdGeneratorFactory::createULID()->generate();
$nanoid  = IdGeneratorFactory::createNanoid()->generate();
$snow    = IdGeneratorFactory::createSnowflake(1, 2)->generate();

$base58  = EncoderFactory::createBase58();
$encoded = $base58->encode($ulid);
$decoded = $base58->decode($encoded);
```

Modules
-------

[](#modules)

Encoders
--------

[](#encoders)

This module provides reversible string encoders that share a simple contract, `EncoderInterface`. Implementations cover Base32, Base58, and Base64 (including a URL-safe variant).

### .1. Contracts and base classes

[](#1-contracts-and-base-classes)

#### .1.1. `Inane\IdForge\Interface\EncoderInterface`

[](#11-inaneidforgeinterfaceencoderinterface)

Contract for reversible string encoders:

- `encode(string $data): string` — converts binary-safe input to an encoded string
- `decode(string $data): string` — converts an encoded string back to the original binary data

Implementations must be deterministic and satisfy `decode(encode($x)) === $x` for valid input. Invalid input should raise `Inane\Stdlib\Exception\InvalidArgumentException` (or a domain-specific exception).

#### .1.2. `Inane\IdForge\Encoder\AbstractEncoder`

[](#12-inaneidforgeencoderabstractencoder)

A small base class that stores an `EncoderConfig` and exposes helpers:

- `getAlphabet(): string`
- `getAlphabetLength(): int`

Concrete encoders (Base32/58/64) extend this class.

### .2. Implementations

[](#2-implementations)

#### .2.1. Base32

[](#21-base32)

Namespace: `Inane\IdForge\Encoder\Base32Encoder`

- Alphabet: configurable (RFC 4648 by default when using `EncoderFactory::createBase32()`)
- Padding: not applied; trailing zero bits are used to complete the last 5-bit group
- Errors: throws `InvalidArgumentException` if a character is not in the alphabet during `decode()`

Usage

```
use Inane\IdForge\EncoderFactory;

$base32 = EncoderFactory::createBase32();
$enc = $base32->encode("\x00\xFFHello");
$bin = $base32->decode($enc);
```

#### .2.2. Base58

[](#22-base58)

Namespace: `Inane\IdForge\Encoder\Base58Encoder`

- Alphabet: configurable (Bitcoin alphabet via `EncoderFactory::createBase58()`)
- Preserves leading zero bytes as leading first-alphabet characters
- Errors: throws `InvalidArgumentException` for unknown characters during `decode()`

Usage

```
use Inane\IdForge\EncoderFactory;

$base58 = EncoderFactory::createBase58();
$enc = $base58->encode("\0\0payload");
$bin = $base58->decode($enc);
```

#### .2.3. Base64

[](#23-base64)

Namespace: `Inane\IdForge\Encoder\Base64Encoder`

- Standard Base64 via `encode()`/`decode()`
- URL-safe helpers: `urlEncode()` replaces `+`/`/` with `-`/`_` and strips padding; `urlDecode()` restores and decodes
- Errors: `decode()` and `urlDecode()` throw `InvalidArgumentException` for invalid Base64 input

Usage (URL-safe)

```
use Inane\IdForge\EncoderFactory;

$base64 = EncoderFactory::createBase64();
$token  = $base64->urlEncode(random_bytes(16));
$bytes  = $base64->urlDecode($token);
```

### .3. Configuration

[](#3-configuration)

Encoders accept `Inane\IdForge\Config\EncoderConfig` which holds:

- `alphabet: string`
- `alphabetLength: int` (precomputed)

Use `EncoderFactory` for sensible defaults or construct encoders manually with a custom alphabet.

### .4. Exceptions

[](#4-exceptions)

- `Inane\Stdlib\Exception\InvalidArgumentException` — invalid input during `decode()`

### .5. See also

[](#5-see-also)

- [Configuration](config.adoc)
- [Factories](factories.adoc)

1. Generators
-------------

[](#1-generators)

IdForge includes several generators that implement a common contract, `IdGeneratorInterface`. Each generator focuses on a different trade-off: interoperability (UUID), sortability (ULID, Snowflake), or brevity and URL-friendliness (Nanoid).

### 1.1. Contract and base class

[](#11-contract-and-base-class)

#### 1.1.1. `Inane\IdForge\Interface\IdGeneratorInterface`

[](#111-inaneidforgeinterfaceidgeneratorinterface)

- `generate(): string` — create a new identifier as a string

Implementations should be fast, low-collision, and safe to use concurrently.

#### 1.1.2. `Inane\IdForge\Generator\AbstractIdGenerator`

[](#112-inaneidforgegeneratorabstractidgenerator)

Provides helpers shared by all generators:

- `getRandomBytes(int $length): string` — cryptographically secure random bytes (can throw `Random\RandomException`)
- `getTimestamp(): int` — current UNIX timestamp in milliseconds

### 1.2. Implementations

[](#12-implementations)

#### 1.2.1. UUIDv4

[](#121-uuidv4)

Namespace: `Inane\IdForge\Generator\UUIDGenerator`

- RFC 4122 UUID version 4
- Format: canonical 36-char string `8-4-4-4-12`
- Helpers:
- `isValid(string $uuid): bool`
- `toBase64(string $uuid, Base64Encoder $base64): string` — URL-safe Base64 (no padding)
- `fromBase64(string $b64, Base64Encoder $base64): string` — back to canonical string
- Errors: `toBase64()` throws `InvalidArgumentException` for invalid input

Usage

```
use Inane\IdForge\IdGeneratorFactory;
use Inane\IdForge\EncoderFactory;

$uuid = IdGeneratorFactory::createUUID()->generate();
$base64 = EncoderFactory::createBase64();
$b64 = IdGeneratorFactory::createUUID()->toBase64($uuid, $base64);
$uuid2 = IdGeneratorFactory::createUUID()->fromBase64($b64, $base64);
```

#### 1.2.2. ULID

[](#122-ulid)

Namespace: `Inane\IdForge\Generator\ULIDGenerator`

- 26-char Crockford Base32, lexicographically sortable
- Structure: 48-bit timestamp + 80 bits randomness
- Monotonic mode ensures strict ordering within the same millisecond
- Key methods:
- `__construct(?EncoderConfig $config = null, bool $monotonic = false)`
- `generate(?int $timestamp = null): string`
- `decodeTimestamp(string $ulid): int`
- `decode(string $ulid): array{timestamp:int, random:string}`
- `toEncoded(EncoderInterface $encoder): string`
- Errors: `InvalidArgumentException` for bad characters/length; `Random\RandomException` for entropy issues

Usage

```
use Inane\IdForge\IdGeneratorFactory;

$ulid = IdGeneratorFactory::createULID()->generate();
```

Monotonic ULID

```
use Inane\IdForge\Generator\ULIDGenerator;
use Inane\IdForge\Config\EncoderConfig;

$mono = new ULIDGenerator(new EncoderConfig('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), true);
$a = $mono->generate();
$b = $mono->generate(); // guaranteed $a < $b when in same ms
```

#### 1.2.3. Nanoid

[](#123-nanoid)

Namespace: `Inane\IdForge\Generator\NanoidGenerator`

- Short, URL-friendly random IDs
- Constructor: `__construct(string $alphabet = '0-9a-zA-Z', int $size = 21)`
- `generate(): string`

Usage

```
use Inane\IdForge\IdGeneratorFactory;

$id = IdGeneratorFactory::createNanoid()->generate();
```

#### 1.2.4. Snowflake-like

[](#124-snowflake-like)

Namespace: `Inane\IdForge\Generator\SnowflakeIdGenerator`

- 64-bit composed numeric ID (as a string): timestamp + datacenter + worker + sequence
- Configured via `SnowflakeConfig` (epoch, bit allocations for worker/datacenter/sequence)
- Methods:
- `__construct(int $workerId = 0, int $datacenterId = 0, ?SnowflakeConfig $config = null)`
- `generate(): string`
- `toEncoded(EncoderInterface $encoder): string`
- Behavior: on sequence overflow within the same millisecond, waits for the next millisecond
- Errors: `RuntimeException` if the clock moves backwards; `InvalidArgumentException` for out-of-range worker/datacenter

Usage

```
use Inane\IdForge\IdGeneratorFactory;

$gen = IdGeneratorFactory::createSnowflake(workerId: 1, datacenterId: 2);
$id  = $gen->generate();
```

### 1.3. See also

[](#13-see-also)

- [Configuration](config.adoc)
- [Factories](factories.adoc)
- [Encoders](encoders.adoc)

2. Configuration
----------------

[](#2-configuration)

This module documents the small configuration objects that accompany encoders and generators.

### 2.1. EncoderConfig

[](#21-encoderconfig)

Namespace: `Inane\IdForge\Config\EncoderConfig`

Holds the alphabet used by encoders and caches its length.

Fields

- `alphabet: string` — characters used by the encoding
- `alphabetLength: int` — cached length of the alphabet

API

- `__construct(string $alphabet)` — set the alphabet and precompute its length
- `getAlphabet(): string`
- `getAlphabetLength(): int`

Usage

```
use Inane\IdForge\Config\EncoderConfig;
use Inane\IdForge\Encoder\Base32Encoder;

$config  = new EncoderConfig('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567');
$encoder = new Base32Encoder($config);
```

### 2.2. SnowflakeConfig

[](#22-snowflakeconfig)

Namespace: `Inane\IdForge\Config\SnowflakeConfig`

Controls the epoch and bit allocations for Snowflake-like IDs.

Fields

- `epoch: int` — custom epoch in milliseconds (default: 1609459200000, 2021-01-01)
- `workerIdBits: int` — bits for worker/node id (default: 5)
- `datacenterIdBits: int` — bits for datacenter id (default: 5)
- `sequenceBits: int` — bits for per-millisecond sequence (default: 12)

API

- `__construct(int $epoch = 1609459200000, int $workerIdBits = 5, int $datacenterIdBits = 5, int $sequenceBits = 12)`
- Getters:
- `getEpoch(): int`
- `getWorkerIdBits(): int`
- `getDatacenterIdBits(): int`
- `getSequenceBits(): int`

Usage

```
use Inane\IdForge\Generator\SnowflakeIdGenerator;
use Inane\IdForge\Config\SnowflakeConfig;

$config = new SnowflakeConfig(epoch: 1700000000000, workerIdBits: 6, datacenterIdBits: 4, sequenceBits: 12);
$gen    = new SnowflakeIdGenerator(workerId: 3, datacenterId: 1, config: $config);
$id     = $gen->generate();
```

### 2.3. See also

[](#23-see-also)

- [Encoders](encoders.adoc)
- [Generators](generators.adoc)
- [Factories](factories.adoc)

3. Factories
------------

[](#3-factories)

Factory helpers provide convenient, opinionated constructors for common encoders and generators.

### 3.1. EncoderFactory

[](#31-encoderfactory)

Namespace: `Inane\IdForge\EncoderFactory`

Creates encoder instances with sensible default alphabets.

API

- `createBase32(): Base32Encoder` — RFC 4648 alphabet `A-Z2-7`
- `createBase58(): Base58Encoder` — Bitcoin alphabet (no `0`, `O`, `I`, `l`)
- `createBase64(): Base64Encoder` — Standard Base64 alphabet

Usage

```
use Inane\IdForge\EncoderFactory;

$base32 = EncoderFactory::createBase32();
$base58 = EncoderFactory::createBase58();
$base64 = EncoderFactory::createBase64();
```

### 3.2. IdGeneratorFactory

[](#32-idgeneratorfactory)

Namespace: `Inane\IdForge\IdGeneratorFactory`

Creates generator instances with defaults and safe validation where applicable.

API

- `createNanoid(string $alphabet = '0-9a-zA-Z', int $size = 21): NanoidGenerator`
- `createSnowflake(int $workerId = 0, int $datacenterId = 0, ?SnowflakeConfig $config = null): SnowflakeIdGenerator`
- `createUUID(): UUIDGenerator`
- `createULID(?EncoderConfig $config = null): ULIDGenerator`

Usage

```
use Inane\IdForge\IdGeneratorFactory;

$uuid   = IdGeneratorFactory::createUUID()->generate();
$ulid   = IdGeneratorFactory::createULID()->generate();
$nanoid = IdGeneratorFactory::createNanoid()->generate();
$snow   = IdGeneratorFactory::createSnowflake(workerId: 1, datacenterId: 2)->generate();
```

### 3.3. See also

[](#33-see-also)

- [Encoders](encoders.adoc)
- [Generators](generators.adoc)
- [Configuration](config.adoc)

4. Example
----------

[](#4-example)

Some examples

```
use Inane\IdForge\Config\EncoderConfig;
use Inane\IdForge\Config\SnowflakeConfig;
use Inane\IdForge\Encoder\AbstractEncoder;
use Inane\IdForge\EncoderFactory;
use Inane\IdForge\Generator\AbstractIdGenerator;
use Inane\IdForge\IdGeneratorFactory;

// Example usage
try {
	// Create encoders via factory
	$base32 = EncoderFactory::createBase32();
	$base58 = EncoderFactory::createBase58();
	$base64 = EncoderFactory::createBase64();

	// Create ID generators via factory
	$nanoid = IdGeneratorFactory::createNanoid();
	$snowflake = IdGeneratorFactory::createSnowflake(1, 1);
	$uuid = IdGeneratorFactory::createUUID();
	$ulid = IdGeneratorFactory::createULID();

	// Base32
	$base32Encoded = $base32->encode('Hello');
	echo "Base32 Encoded: $base32Encoded\n";
	echo 'Base32 Decoded: ' . $base32->decode($base32Encoded) . "\n";
	echo PHP_EOL;

	// Base58
	$base58Encoded = $base58->encode('Hello');
	echo "Base58 Encoded: $base58Encoded\n";
	echo 'Base58 Decoded: ' . $base58->decode($base58Encoded) . "\n";
	echo PHP_EOL;

	// Base64
	$base64Encoded = $base64->urlEncode('Hello');
	echo "Base64 URL Encoded: $base64Encoded\n";
	echo 'Base64 URL Decoded: ' . $base64->urlDecode($base64Encoded) . "\n";
	echo PHP_EOL;

	// Nanoid
	echo 'Nanoid: ' . $nanoid->generate() . "\n";
	echo PHP_EOL;

	// Snowflake ID
	$snowflakeId = $snowflake->generate();
	echo "Snowflake ID: $snowflakeId\n";
	echo 'Snowflake ID (Base58): ' . $snowflake->toEncoded($base58) . "\n";
	echo PHP_EOL;

	// UUID
	$uuidValue = $uuid->generate();
	echo "UUID: $uuidValue\n";
	$uuidBase64 = $uuid->toBase64($uuidValue, $base64);
	echo "UUID Base64: $uuidBase64\n";
	echo 'UUID from Base64: ' . $uuid->fromBase64($uuidBase64, $base64) . "\n";
	echo PHP_EOL;

	// ULID
	$ulidValue = $ulid->generate();
	echo "ULID: $ulidValue\n";
	echo 'ULID Timestamp: ' . $ulid->decodeTimestamp($ulidValue) . "\n";
	echo 'ULID Base32: ' . $ulid->toEncoded($base32) . "\n";
	echo PHP_EOL;

	// ULID
	$ulidValue = $ulid->generate(1761168799791);
	echo "ULID 2: $ulidValue\n";
	echo 'ULID 2 Timestamp: ' . $ulid->decodeTimestamp($ulidValue) . "\n";
	echo 'ULID 2 Base32: ' . $ulid->toEncoded($base32) . "\n";
} catch (Exception $e) {
	echo 'Error: ' . $e->getMessage() . "\n";
}

// Add a New Encoder:
class Base16Encoder extends AbstractEncoder {
	public function __construct() {
		parent::__construct(new EncoderConfig('0123456789ABCDEF'));
	}

	public function encode(string $data): string {
		return strtoupper(bin2hex($data));
	}

	public function decode(string $data): string {
		return hex2bin($data);
	}
}

class Encoder2Factory {
	public static function createBase16(): Base16Encoder {
		return new Base16Encoder();
	}
}

$base16 = Encoder2Factory::createBase16()->encode('Hello');
$text = Encoder2Factory::createBase16()->decode($base16);
$line("Base16:encoded: $base16");
$line("Base16:decoded: $text");
// EncoderFactory::createBase16 = fn() => new Base16Encoder();

// Add a New ID Generator:
class CustomIdGenerator extends AbstractIdGenerator {
	public function generate(): string {
		$timestamp = $this->getTimestamp();
		$random = $this->getRandomBytes(8);
		return bin2hex($timestamp . $random);
	}
}

class IdGenerator2Factory {
	public static function createCustomId(): CustomIdGenerator {
		return new CustomIdGenerator();
	}
}

$customId = IdGenerator2Factory::createCustomId()->generate();
$line("CustomID: $customId");

// IdGeneratorFactory::createCustomId = fn() => new CustomIdGenerator();

// Customize Snowflake Configuration:
$customConfig = new SnowflakeConfig(1640995200000, 4, 4, 10); // Custom epoch, fewer bits
$snowflake = IdGeneratorFactory::createSnowflake(1, 1, $customConfig);

// Custom Alphabet for Nanoid:
$nanoid = IdGeneratorFactory::createNanoid('0123456789abcdef', 12); // Hex-only, shorter length
```

5. Error handling
-----------------

[](#5-error-handling)

- Most decoders will throw `Inane\Stdlib\Exception\InvalidArgumentException` when the input contains invalid characters or cannot be parsed.
- `SnowflakeIdGenerator::generate()` can throw `Inane\Stdlib\Exception\RuntimeException` if it detects a system clock moving backwards.
- Generators that rely on randomness may throw `Random\RandomException` from PHP core when entropy is not available.

6. When to use which generator
------------------------------

[](#6-when-to-use-which-generator)

- UUIDv4: Standard interoperable identifiers, not sortable, 36 chars.
- ULID: 26-char, lexicographically sortable, timestamp + randomness; good for DB keys and logs.
- Nanoid: Short, URL-friendly IDs with controllable alphabet and size.
- Snowflake: Numeric IDs composed of timestamp + worker/datacenter + sequence; good for distributed systems that need k-sortable numbers.

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance79

Regular maintenance activity

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity44

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

201d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1823594?v=4)[Philip Michael Raab](/maintainers/inanepain)[@inanepain](https://github.com/inanepain)

---

Top Contributors

[![inanepain](https://avatars.githubusercontent.com/u/1823594?v=4)](https://github.com/inanepain "inanepain (19 commits)")

---

Tags

base32base58base64cryptographyencodingid-forgeid-generationinanepainlibrarynanoidphpsnowflakeidulidunique-identifieruuidphpcryptographyencodingbase64uuidbase32ulidinanepainbase58unique identifiernanoidid-generationid-forgesnowflakeid

### Embed Badge

![Health badge](/badges/inanepain-id-forge/health.svg)

```
[![Health](https://phpackages.com/badges/inanepain-id-forge/health.svg)](https://phpackages.com/packages/inanepain-id-forge)
```

###  Alternatives

[paragonie/constant_time_encoding

Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)

901329.7M148](/packages/paragonie-constant-time-encoding)[xobotyi/basen

Text and integers encoding utilities for PHP with no extensions dependencies. Base32, Base58, Base64 and much more!

1219.6k](/packages/xobotyi-basen)[riipandi/laravel-optikey

Use UUID, Ulid, or nanoid as optional or primary key in Laravel.

429.1k](/packages/riipandi-laravel-optikey)[fab2s/souuid

Simple Ordered Uuid Generator in PHP

13573.2k1](/packages/fab2s-souuid)[ramsey/identifier

A PHP library for generating and working with identifiers, including UUIDs, ULIDs, and Snowflakes

603.0k1](/packages/ramsey-identifier)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
