ChaosRNG: PHP Pseudo-Random Byte Generator Using 12 Timers
The ChaosRNG class leverages 12 interconnected timers to generate bytes with entropy up to 7.1–8 bits per byte. Each timer adds nonlinearity—from base time and nanoseconds to pauses and zero-byte insertions. This experimental approach suits tasks that don't need certified cryptographic primitives.
The constructor initializes the state via XOR of microseconds (T1), nanoseconds (T2), PID, and memory usage (T7). The distortion factor starts at 1.001, with the switch enabled by default.
Timer Logic
The timers form a processing pipeline:
- T1: Microseconds since 1970.
- T2: Nanoseconds since system boot.
- T3: Updates 64-bit state by adding or subtracting the lowest byte of total.
- T4: Modulates time by multiplying/dividing by factor k, updated each cycle.
- T5: Determines slices (1000–10000).
- T6: Selects slice for time weighting.
- T7: Cache and interrupt jitter via PID and memory.
- T8: Switch—skips real bytes when off.
- T9: Controls T8 based on last byte (<5 on, >5 off).
- T10: Hidden start point in constructor.
- T11: Inserts 0x00 when ($state & 10) === 0.
- T12: Pauses 1–100 cycles with state updates during wait.
/**
* ChaosRNG - random byte generator with 12 timers
*
* 12 timers:
* T1 – standard clock (microtime)
* T2 – high-res clock (hrtime)
* T3 – memory (state $state)
* T4 – distorter (multiplies/divides time)
* T5 – slicer (1000-10000 slices)
* T6 – picker (slice selector)
* T7 – hidden noise (jitter, interrupts)
* T8 – switch (on/off output)
* T9 – watcher (controls switch)
* T10 – start point (init moment)
* T11 – blob (zero byte insert)
* T12 – silencer (1-100 cycle pauses)
*/
class ChaosRNG {
// Class properties
private $state; // T3: 64-bit state
private $k; // T4: distortion factor
private $enabled; // T8: switch (on/off)
private $lastByte; // T9: last output byte
private $dot; // T11: dot flag
private $pauseLen; // T12: pause length
private $pauseRem; // T12: pause remainder
/**
* Constructor — T10 (start point)
* Mixes all unrepeatable sources
*/
public function __construct() {
// XOR all sources → unique initial state
$this->state = (int)(microtime(true) * 1000000) // T1: microseconds
^ hrtime(true) // T2: nanoseconds
^ getmypid() // T7: process PID
^ memory_get_usage(); // T7: memory usage
$this->k = 1.001; // T4: initial factor
$this->enabled = true; // T8: switch on
$this->lastByte = 0; // T9: no last byte
$this->dot = false; // T11: no dot inserted
$this->pauseLen = 0; // T12: no pause
$this->pauseRem = 0; // T12: remainder 0
}
/**
* T1: standard clock
* Returns microseconds since 1970
*/
private function t1() {
return (int)(microtime(true) * 1000000);
}
/**
* T2: high-res clock
* Returns nanoseconds since boot
*/
private function t2() {
return hrtime(true);
}
/**
* Internal byte generator (T3-T7)
* Updates state and returns one byte
*/
private function nextByteInternal() {
// T5: slice count 1000 to 10000
$K = 1000 + ($this->state % 9001);
// T6: select specific slice
$slot = (($this->state >> 8) % $K);
// T1 and T2: get current time
$t1 = $this->t1();
$t2 = $this->t2();
// T4: distorter (stretch or compress time)
if ($this->state & 1) {
$t1 = $t1 * $this->k; // stretch T1
} else {
$t2 = $t2 / $this->k; // compress T2
}
// Sum with selected slice
$total = (int)($t1 * ($slot + 1) / $K)
+ (int)($t2 * ($slot + 1) / $K);
// T3: update state (add or subtract)
if ($total & 1) {
$this->state += ($total & 0xFF);
} else {
$this->state -= ($total & 0xFF);
}
// Update distortion factor
$this->k = 1.0 + (($this->state & 0xFF) / 10000.0);
// Return lowest state byte
return $this->state & 0xFF;
}
/**
* Public method: get N random bytes
* Accounts for all 12 timers
*/
public function getBytes($n) {
$out = [];
for ($i = 0; $i < $n; $i++) {
// T12: pause (silencer)
while ($this->pauseRem > 0) {
$this->pauseRem--;
$this->nextByteInternal(); // state changes
}
// If pause ended — generate new one
if ($this->pauseRem === 0 && $this->pauseLen === 0) {
$this->pauseLen = 1 + ($this->state % 100); // 1-100 cycles
$this->pauseRem = $this->pauseLen;
}
// T11: dot (zero byte insert)
if (($this->state & 10) === 0 && !$this->dot) {
$this->dot = true;
$this->nextByteInternal();
$out[] = 0x00; // dot = zero byte
continue;
}
$this->dot = false;
// T9: switch watcher
if ($this->lastByte < 5) {
$this->enabled = true; // turn on
} elseif ($this->lastByte > 5) {
$this->enabled = false; // turn off
}
// if ==5, no change
// Generate byte
$byte = $this->nextByteInternal();
// T8: switch
if (!$this->enabled) {
// If off — output dummy byte
$out[] = $this->nextByteInternal() & 0xFF;
continue;
}
// Save last output byte
$this->lastByte = $byte;
// Reset pause after real byte
if ($this->pauseLen > 0) {
$this->pauseLen = 0;
$this->pauseRem = 0;
}
$out[] = $byte;
}
return $out;
}
}
Shannon Entropy Calculation
The static entropy() method computes Shannon entropy using -Σ p * log2(p) for byte frequencies. Tests on 64 KB data show an average of 7.12 bits.
public static function entropy($bytes) {
// Count byte frequencies
$freq = array_fill(0, 256, 0);
foreach ($bytes as $b) {
$freq[$b]++;
}
// Shannon formula: -Σ p * log2(p)
$e = 0;
$total = count($bytes);
foreach ($freq as $c) {
if ($c > 0) {
$p = $c / $total;
$e -= $p * log($p, 2);
}
}
return $e;
}
// Test
$rng = new ChaosRNG();
$data = $rng->getBytes(65536);
$entropy = ChaosRNG::entropy($data);
echo "Entropy: " . round($entropy, 4) . " / 8 bits\n";
Nonlinearity and Resilience
Recovering the state requires knowing k, slice count, pauses, and switch position. The 64-bit state hinders attacks without server access. Entropy >6.5 bits even on VMs makes the sequence statistically close to random.
Use cases: token and password generation (16 chars ~113 bits entropy). Not for cryptography—experiments only.
Key Takeaways
- 12 timers create a nonlinear pipeline with pauses and skips to thwart analysis.
- Shannon entropy 7.1+ bits per byte, tested on 64 KB.
- T12 (pauses) and T11 (zeros) break temporal and sequential predictability.
- 64-bit state balances resilience and speed.
- Not for production crypto: experimental PRNG.
— Editorial Team
No comments yet.