PHPackages                             michaelfrank-dev/php-trng - 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. michaelfrank-dev/php-trng

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

michaelfrank-dev/php-trng
=========================

Robust PHP library for retrieving true random numbers (TRNG) from quantum and hardware sources, featuring rejection sampling and resilient fallback chains.

v1.0.0(1mo ago)00MITPHPPHP ^8.3

Since May 4Pushed 1mo agoCompare

[ Source](https://github.com/michaelfrank-dev/php-trng)[ Packagist](https://packagist.org/packages/michaelfrank-dev/php-trng)[ RSS](/packages/michaelfrank-dev-php-trng/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (1)Dependencies (4)Versions (2)Used By (0)

PHP TRNG
========

[](#php-trng)

[![Minimum PHP Version](https://camo.githubusercontent.com/e69fc10ad0d3845d44d08b0eeedd6dd7a5bfa4ab872e68e26b131554122d35d5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e332d626c75652e737667)](https://php.net/)![Platform: 64-bit](https://camo.githubusercontent.com/1676820b8b90592b0888dd7d5299d8682e1f80cbc96409ed7bdaa13ba003ae7e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f706c6174666f726d2d36342d2d6269742d6c69676874677265792e737667)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](https://opensource.org/licenses/MIT)

PHP library for retrieving True Random Numbers (TRNG) from multiple external hardware and quantum entropy sources.

Whether you need true, non-deterministic random numbers for cryptographic seeding, randomized trials, simulations, or procedural generation, this library provides a clean interface to fetch `uint8` or `uint16` integers natively. It features granular exception handling to allow resilient fallback chains.

Features
--------

[](#features)

- **Multiple Entropy Sources**: Native support for [RANDOM.ORG](https://www.random.org), [ANU Quantum Random Numbers](https://quantumnumbers.anu.edu.au), and the [Drand Distributed Randomness Beacon](https://drand.love/).
- **Unbiased Range Generation**: Includes an `EntropyBuffer` that derives specific types, bounds, and ranges safely without modular bias (rejection sampling).
- **Flexible Authentication**: Most providers can be configured with or without API keys, adapting to your usage volume and tier.
- **Smart Limitations Bypass**: Gracefully unpacks values behind the scenes when service quotas restrict payload limits (e.g., doubling `uint8` output limits on ANU).

Installation
------------

[](#installation)

Install via Composer:

```
composer require michaelfrank-dev/php-trng
```

> **PSR-18 Requirement:** This package requires a PSR-18 HTTP Client and PSR-17 HTTP Factories. If you don't already have one in your project, install Guzzle:
>
> ```
> composer require guzzlehttp/guzzle
> ```

> **64-bit PHP Required:** `EntropyBuffer::toInteger(8)` reads a 64-bit unsigned integer using `unpack('J', ...)`. On a 32-bit PHP build, values exceeding `PHP_INT_MAX` are silently returned as floats, breaking type safety. **This library requires a 64-bit PHP build.**

---

Fetching Raw Random Numbers
---------------------------

[](#fetching-raw-random-numbers)

The simplest use case is fetching raw random integers directly from a provider. All providers implement a `getValues(int $length, TrngType $type)` method that returns a plain PHP array.

### RANDOM.ORG

[](#randomorg)

Can be used with or without an API key.

- **Without an API Key** — uses the legacy plain-text API.
- **With an API Key** — upgrades to the JSON-RPC v4 API for higher limits and quota telemetry.

> **Terms of Use:** The RANDOM.ORG open API is subject to fair-use rate limits and other restrictions. Review the [usage guidelines](https://www.random.org/terms/) before integrating it into production applications.

```
use MichaelFrank\Trng\Providers\RandomOrgProvider;
use MichaelFrank\Trng\TrngType;

// Without API key (legacy plain-text API)
$provider = new RandomOrgProvider();
$bytes = $provider->getValues(100, TrngType::UINT8);
// $bytes => [142, 7, 203, 88, ...]  (100 integers, each 0-255)

// With API key (JSON-RPC v4 API)
$provider = RandomOrgProvider::withApiKey('your-api-key-here');
$integers = $provider->getValues(50, TrngType::UINT16);
// $integers => [41230, 8912, 60001, ...]  (50 integers, each 0-65535)

// Quota metadata is available after any authenticated call
$metadata = $provider->getLastMetadata();
// e.g., ['requestsLeft' => 999, 'bitsLeft' => 249000, ...]
```

### ANU Quantum Random Numbers (QRNG)

[](#anu-quantum-random-numbers-qrng)

Can be used with or without an API key.

> **Deprecation Notice:** The unauthenticated ANU endpoint (`qrng.anu.edu.au`) is being phased out and may be unavailable in the future. It is strongly recommended to [register for an API key](https://quantumnumbers.anu.edu.au) and use `AnuProvider::withApiKey()` for any production usage.

> **Note on API Limits:** The ANU API enforces a strict limit of 1,024 items per request. When you request more than 1,024 `uint8` values, the library automatically requests `uint16` from the API and unpacks them internally, yielding up to 2,048 `uint8` values transparently.

```
use MichaelFrank\Trng\Providers\AnuProvider;
use MichaelFrank\Trng\TrngType;

// Without API key
$provider = new AnuProvider();
$bytes = $provider->getValues(100, TrngType::UINT8);
// $bytes => [57, 200, 14, 99, ...]  (100 integers, each 0-255)

// Requesting more than 1024 uint8 — the library handles the unpacking internally
$bytes = $provider->getValues(2000, TrngType::UINT8);
// $bytes => [...]  (2000 integers, each 0-255)

// Requesting uint16 directly (max 1024)
$integers = $provider->getValues(100, TrngType::UINT16);
// $integers => [41230, 8912, 60001, ...]  (100 integers, each 0-65535)

// With API key
$provider = AnuProvider::withApiKey('your-api-key-here');
$bytes = $provider->getValues(512, TrngType::UINT8);
```

### Drand (Distributed Randomness Beacon)

[](#drand-distributed-randomness-beacon)

Drand yields exactly **32 bytes** (or **16 uint16 values**) per beacon call. No API key is required. The beacon signature is verified automatically to ensure cryptographic integrity. Note: It does not verify the drand BLS signature against the chain public key.

This provider targets the **[Quicknet](https://docs.drand.love/blog/2023/10/16/quicknet-is-live/)** chain by default (`QUICKNET_CHAIN_HASH`), which operates on a 3-second pulse interval with unchained, threshold BLS randomness.

```
use MichaelFrank\Trng\Providers\DrandProvider;
use MichaelFrank\Trng\TrngType;

$provider = new DrandProvider();

// Fetch up to 32 bytes
$bytes = $provider->getValues(32, TrngType::UINT8);
// $bytes => [...]  (32 integers, each 0-255)

// Fetch up to 16 uint16 values
$integers = $provider->getValues(16, TrngType::UINT16);
// $integers => [...]  (16 integers, each 0-65535)

// Use a custom chain or relay
$provider = DrandProvider::forChain('your-chain-hash', ['https://your.relay.example.com']);

// Disable beacon signature verification (not recommended for production)
$provider = (new DrandProvider())->withoutVerification();
```

---

Consuming Entropy Safely with EntropyBuffer
-------------------------------------------

[](#consuming-entropy-safely-with-entropybuffer)

Raw random integers are useful on their own, but using modulo (`%`) to fit them into a range introduces **modular bias**, which skews the distribution. The `EntropyBuffer` class solves this by using **rejection sampling** to guarantee a perfectly uniform distribution.

> **Important:** `EntropyBuffer` operates on **bytes (uint8, values 0-255)**. If you fetched `uint16` values from a provider, you must convert them first using `EntropyBuffer::fromUint16()`.

### Example: From uint8 (direct)

[](#example-from-uint8-direct)

```
use MichaelFrank\Trng\Providers\AnuProvider;
use MichaelFrank\Trng\EntropyBuffer;
use MichaelFrank\Trng\TrngType;

$provider = new AnuProvider();
$bytes = $provider->getValues(64, TrngType::UINT8);

$buffer = new EntropyBuffer($bytes);

// Unbiased integer in a precise range (e.g., roll a six-sided die)
$diceRoll = $buffer->toRange(1, 6);

// Uniform float in [0.0, 1.0)
$float = $buffer->toFloat();

// Consume the next N bytes from the buffer (cursor advances)
$chunk = $buffer->nextBytes(4);

// Export the full buffer as hex or a binary string
$hex = $buffer->toHex();
$binary = $buffer->toBinaryString();

// Check how many bytes are still available
$remaining = $buffer->remaining();
```

### Example: From uint16 (use the helper)

[](#example-from-uint16-use-the-helper)

When you fetch `uint16` values from a provider, pass them through `EntropyBuffer::fromUint16()`. It splits each 16-bit integer into two bytes (Big Endian) and returns a ready-to-use buffer with double the entropy.

```
use MichaelFrank\Trng\Providers\AnuProvider;
use MichaelFrank\Trng\EntropyBuffer;
use MichaelFrank\Trng\TrngType;

$provider = new AnuProvider();
$uint16s = $provider->getValues(16, TrngType::UINT16);
// $uint16s => [41230, 8912, ...]  (16 integers, each 0-65535)

// Convert to a byte buffer — each uint16 becomes 2 bytes (32 bytes total)
$buffer = EntropyBuffer::fromUint16($uint16s);

$diceRoll = $buffer->toRange(1, 6);
$float = $buffer->toFloat();
```

> Passing `uint16` values directly to `new EntropyBuffer()` will throw an `\InvalidArgumentException`, as the constructor enforces that all values are valid bytes (0-255).

---

Exception Handling &amp; Fallback Chains
----------------------------------------

[](#exception-handling--fallback-chains)

When working with external HTTP APIs, resilient error handling is critical. The library defines granular exceptions that all extend the base `TrngException` class.

ExceptionWhen it is thrown`TrngRateLimitException`HTTP 429 or quota exhaustion`TrngNetworkException`DNS failure, timeout, or unreachable host`TrngServerException`HTTP 5xx server errors`TrngInvalidResponseException`Malformed JSON, missing fields, or failed beacon integrity check`TrngException`Base class; catches all of the aboveThe example below demonstrates a complete three-tier fallback chain across all providers:

```
use MichaelFrank\Trng\Providers\RandomOrgProvider;
use MichaelFrank\Trng\Providers\AnuProvider;
use MichaelFrank\Trng\Providers\DrandProvider;
use MichaelFrank\Trng\TrngType;

use MichaelFrank\Trng\Exceptions\TrngException;
use MichaelFrank\Trng\Exceptions\TrngNetworkException;
use MichaelFrank\Trng\Exceptions\TrngRateLimitException;
use MichaelFrank\Trng\Exceptions\TrngServerException;
use MichaelFrank\Trng\Exceptions\TrngInvalidResponseException;

$length = 256;
$type   = TrngType::UINT8;
$result = [];

try {
    // Primary: RANDOM.ORG (authenticated)
    $provider = RandomOrgProvider::withApiKey('your-api-key-here');
    $result = $provider->getValues($length, $type);

} catch (TrngRateLimitException $e) {
    // HTTP 429 or quota exhausted
    error_log('RANDOM.ORG quota depleted: ' . $e->getMessage());
    $result = fallbackToQuantum($length, $type);

} catch (TrngNetworkException $e) {
    // DNS failure, timeout, or host unreachable
    error_log('Network failure: ' . $e->getMessage());
    $result = fallbackToQuantum($length, $type);

} catch (TrngServerException $e) {
    // HTTP 5xx
    error_log('Provider server error: ' . $e->getMessage());
    $result = fallbackToQuantum($length, $type);

} catch (TrngInvalidResponseException $e) {
    // Malformed payload or failed integrity check
    error_log('Invalid response: ' . $e->getMessage());
    $result = fallbackToQuantum($length, $type);

} catch (TrngException $e) {
    // Catch-all for any other library exception
    error_log('Unexpected TRNG error: ' . $e->getMessage());
    $result = fallbackToQuantum($length, $type);

} catch (\InvalidArgumentException $e) {
    // Invalid $length or $type parameters
    error_log('Invalid arguments: ' . $e->getMessage());
}

function fallbackToQuantum(int $length, TrngType $type): array
{
    try {
        // Secondary: ANU Quantum (no key needed)
        return (new AnuProvider())->getValues($length, $type);

    } catch (TrngException $e) {
        // Last resort: Drand beacon (max 32 bytes per call)
        return (new DrandProvider())->getValues(min($length, 32), $type);
    }
}
```

---

License
-------

[](#license)

This library is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

###  Health Score

39

—

LowBetter than 84% of packages

Maintenance93

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

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

36d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6af4e1e403510c538cdc41a5ca209d36cda43d930d1ec36ca456f0f7744112fd?d=identicon)[michaelfrank-dev](/maintainers/michaelfrank-dev)

---

Top Contributors

[![michaelfrank-dev](https://avatars.githubusercontent.com/u/213680755?v=4)](https://github.com/michaelfrank-dev "michaelfrank-dev (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/michaelfrank-dev-php-trng/health.svg)

```
[![Health](https://phpackages.com/badges/michaelfrank-dev-php-trng/health.svg)](https://phpackages.com/packages/michaelfrank-dev-php-trng)
```

###  Alternatives

[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

35729.6k2](/packages/telnyx-telnyx-php)[tempest/framework

The PHP framework that gets out of your way.

2.2k31.1k11](/packages/tempest-framework)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

84735.1k](/packages/flow-php-flow)[anthropic-ai/sdk

Anthropic PHP SDK

155372.1k13](/packages/anthropic-ai-sdk)[chargebee/chargebee-php

ChargeBee API client implementation for PHP

788.3M9](/packages/chargebee-chargebee-php)[florianv/exchanger

PHP exchange rate provider layer for currency conversion: 30 services, chain fallback, and caching.

1854.9M19](/packages/florianv-exchanger)

PHPackages © 2026

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