1<?php 2 3namespace Random\Engine\Test; 4 5use Random\Engine; 6 7final class TestShaEngine implements Engine 8{ 9 private string $state; 10 11 public function __construct(?string $state = null) 12 { 13 if ($state !== null) { 14 $this->state = $state; 15 } else { 16 $this->state = random_bytes(20); 17 } 18 } 19 20 public function generate(): string 21 { 22 $this->state = sha1($this->state, true); 23 24 return substr($this->state, 0, 8); 25 } 26} 27 28final class TestWrapperEngine implements Engine 29{ 30 private int $count = 0; 31 32 public function __construct(private readonly Engine $engine) 33 { 34 } 35 36 public function generate(): string 37 { 38 $this->count++; 39 40 return $this->engine->generate(); 41 } 42 43 public function getCount(): int 44 { 45 return $this->count; 46 } 47} 48 49final class TestXoshiro128PlusPlusEngine implements Engine 50{ 51 public function __construct( 52 private int $s0, 53 private int $s1, 54 private int $s2, 55 private int $s3 56 ) { 57 } 58 59 private static function rotl($x, $k) 60 { 61 return (($x << $k) | ($x >> (32 - $k))) & 0xFFFFFFFF; 62 } 63 64 public function generate(): string 65 { 66 $result = (self::rotl(($this->s0 + $this->s3) & 0xFFFFFFFF, 7) + $this->s0) & 0xFFFFFFFF; 67 68 $t = ($this->s1 << 9) & 0xFFFFFFFF; 69 70 $this->s2 ^= $this->s0; 71 $this->s3 ^= $this->s1; 72 $this->s1 ^= $this->s2; 73 $this->s0 ^= $this->s3; 74 75 $this->s2 ^= $t; 76 77 $this->s3 = self::rotl($this->s3, 11); 78 79 return pack('V', $result); 80 } 81} 82 83final class TestCountingEngine32 implements Engine 84{ 85 private int $count = 0; 86 87 public function generate(): string 88 { 89 return pack('V', $this->count++); 90 } 91} 92 93final class TestCountingEngine64 implements Engine 94{ 95 private int $count = 0; 96 97 public function generate(): string 98 { 99 if ($this->count > 2147483647 || $this->count < 0) { 100 throw new \Exception('Overflow'); 101 } 102 return pack('V', $this->count++) . "\x00\x00\x00\x00"; 103 } 104} 105 106?> 107