Generátor pseudonáhodných bajtů využívající 12 časovačů v PHP
Třída ChaosRNG využívá 12 vzájemně propojených časovačů k generování bajtů s entropií až 7,1–8 bitů na symbol. Každý časovač přispívá nelinearitou: od základního času a nanosekund po pauzy a vkládání nulových bajtů. Toto je experimentální přístup pro úlohy, které nevyžadují certifikované kryptografické primitivy.
Konstruktor inicializuje stav pomocí XOR mikrosekund (T1), nanosekund (T2), PID a paměti (T7). Koeficient křivosti začíná na 1,001, vypínač je ve výchozím nastavení zapnut.
Logika časovačů
Časovače tvoří zpracovatelský konveyor:
- T1: mikrosekundy od roku 1970.
- T2: nanosekundy od spuštění systému.
- T3: aktualizace 64bitového stavu — přičtení nebo odečtení nejnižšího bajtu celkového součtu.
- T4: modulace času násobením/dělením koeficientem k, který se aktualizuje každý takt.
- T5: určuje řezy (1000–10000).
- T6: vybírá řez pro vážení času.
- T7: džitter cache a přerušení přes PID a paměť.
- T8: vypínač — přeskočení skutečných bajtů při vypnutém stavu.
- T9: řídí T8 podle posledního bajtu (<5 — zapnuto, >5 — vypnuto).
- T10: skrytý počáteční bod v konstruktoru.
- T11: vložení 0x00 při ($state & 10) === 0.
- T12: pauzy 1–100 taktů s aktualizací stavu během čekání.
/**
* ChaosRNG - generátor náhodných bajtů s 12 časovači
*
* 12 časovačů:
* T1 – běžné hodiny (microtime)
* T2 – přesné hodiny (hrtime)
* T3 – paměť (stav $state)
* T4 – křivka (násobí/dělí čas)
* T5 – drtič (počet řezů 1000-10000)
* T6 – ukazovák (výběr řezu)
* T7 – skrytý šum (džitter, přerušení)
* T8 – vypínač (zap/vyp výstupu)
* T9 – pozorovatel (řídí vypínač)
* T10 – počáteční bod (moment inicializace)
* T11 – kaňka (vložení nulového bajtu)
* T12 – tichoun (pauzy 1-100 taktů)
*/
class ChaosRNG {
// Vlastnosti třídy
private $state; // T3: 64bitový stav
private $k; // T4: koeficient křivosti
private $enabled; // T8: vypínač (zap/vyp)
private $lastByte; // T9: poslední vydaný bajt
private $dot; // T11: příznak bodu
private $pauseLen; // T12: délka pauzy
private $pauseRem; // T12: zbytek pauzy
/**
* Konstruktor — T10 (počáteční bod)
* Smícháme vše, co nelze opakovat
*/
public function __construct() {
// XOR všech zdrojů → unikátní počáteční stav
$this->state = (int)(microtime(true) * 1000000) // T1: mikrosekundy
^ hrtime(true) // T2: nanosekundy
^ getmypid() // T7: PID procesu
^ memory_get_usage(); // T7: využitá paměť
$this->k = 1.001; // T4: počáteční koeficient
$this->enabled = true; // T8: vypínač zapnut
$this->lastByte = 0; // T9: poslední bajt není
$this->dot = false; // T11: bod nevložen
$this->pauseLen = 0; // T12: pauza není
$this->pauseRem = 0; // T12: zbytek pauzy = 0
}
/**
* T1: běžné hodiny
* Vrací mikrosekundy od roku 1970
*/
private function t1() {
return (int)(microtime(true) * 1000000);
}
/**
* T2: přesné hodiny
* Vrací nanosekundy od spuštění systému
*/
private function t2() {
return hrtime(true);
}
/**
* Vnitřní generátor bajtu (T3-T7)
* Mění stav a vrací jeden bajt
*/
private function nextByteInternal() {
// T5: počet řezů od 1000 do 10000
$K = 1000 + ($this->state % 9001);
// T6: výběr konkrétního řezu
$slot = (($this->state >> 8) % $K);
// T1 a T2: získáváme aktuální čas
$t1 = $this->t1();
$t2 = $this->t2();
// T4: křivka (natahujeme nebo stlačujeme čas)
if ($this->state & 1) {
$t1 = $t1 * $this->k; // natahujeme T1
} else {
$t2 = $t2 / $this->k; // stlačujeme T2
}
// Sečteme s ohledem na vybraný řez
$total = (int)($t1 * ($slot + 1) / $K)
+ (int)($t2 * ($slot + 1) / $K);
// T3: aktualizujeme stav (přičteme nebo odečteme)
if ($total & 1) {
$this->state += ($total & 0xFF);
} else {
$this->state -= ($total & 0xFF);
}
// Aktualizujeme koeficient křivosti
$this->k = 1.0 + (($this->state & 0xFF) / 10000.0);
// Vracíme nejnižší bajt stavu
return $this->state & 0xFF;
}
/**
* Veřejná metoda: získat N náhodných bajtů
* Bere v úvahu všech 12 časovačů
*/
public function getBytes($n) {
$out = [];
for ($i = 0; $i < $n; $i++) {
// T12: pauza (tichoun)
while ($this->pauseRem > 0) {
$this->pauseRem--;
$this->nextByteInternal(); // stav se mění
}
// Pokud pauza skončila — generujeme novou
if ($this->pauseRem === 0 && $this->pauseLen === 0) {
$this->pauseLen = 1 + ($this->state % 100); // 1-100 taktů
$this->pauseRem = $this->pauseLen;
}
// T11: bod (vložení nulového bajtu)
if (($this->state & 10) === 0 && !$this->dot) {
$this->dot = true;
$this->nextByteInternal();
$out[] = 0x00; // bod = nulový bajt
continue;
}
$this->dot = false;
// T9: pozorovatel za vypínačem
if ($this->lastByte < 5) {
$this->enabled = true; // zapneme
} elseif ($this->lastByte > 5) {
$this->enabled = false; // vypneme
}
// pokud rovno 5 — nic neměníme
// Generujeme bajt
$byte = $this->nextByteInternal();
// T8: vypínač
if (!$this->enabled) {
// Pokud vypnut — vydáme fiktivní bajt
$out[] = $this->nextByteInternal() & 0xFF;
continue;
}
// Uložíme poslední vydaný bajt
$this->lastByte = $byte;
// Resetujeme pauzu po vydání skutečného bajtu
if ($this->pauseLen > 0) {
$this->pauseLen = 0;
$this->pauseRem = 0;
}
$out[] = $byte;
}
return $out;
}
}
Výpočet Shannonovy entropie
Statická metoda entropy() vypočítává entropii podle vzorce -Σ p * log2(p) pro frekvence bajtů. Test na 64 KB dat ukazuje průměrně 7,12 bitů.
public static function entropy($bytes) {
// Počítáme frekvenci každého bajtu
$freq = array_fill(0, 256, 0);
foreach ($bytes as $b) {
$freq[$b]++;
}
// Shannonův vzorec: -Σ 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 "Entropie: " . round($entropy, 4) . " / 8 bitů\n";
Nelinearita a odolnost
Obnovení stavu vyžaduje znalost k, počtu řezů, pauz, polohy vypínače. Stav 64 bitů komplikuje útoky bez přístupu k serveru. Entropie >6,5 bitů i na virtualizacích činí sekvenci statisticky blízkou náhodné.
Použití: generování tokenů, hesel (16 znaků ~113 bitů entropie). Ne pro kryptografii — pouze experimenty.
Co je důležité
- 12 časovačů vytváří nelineární konveyor s pauzami a přeskoky pro ztížení analýzy.
- Shannonova entropie 7,1+ bitů na bajt, test na 64 KB.
- T12 (pauzy) a T11 (nuly) narušují časovou a sekvenční předvídatelnost.
- Stav 64 bitů — kompromis mezi odolností a rychlostí.
- Nepoužívat v production kryptografii: experimentální PRNG.
— Editorial Team
Zatím žádné komentáře.