Page MenuHomeWickedGov Phorge

Alea.php
No OneTemporary

Size
3 KB
Referenced Files
None
Subscribers
None

Alea.php

<?php
declare( strict_types = 1 );
namespace Wikimedia\Alea;
/**
* Alea non-cryptographic pseudo-random number generator.
*
* Compatible with https://www.npmjs.com/package/alea
*
* From http://baagoe.com/en/RandomMusings/javascript/
*
* Archived at:
* * https://web.archive.org/web/20120619002808/http://baagoe.org/en/wiki/Better_random_numbers_for_javascript
* * https://web.archive.org/web/20120502223108/http://baagoe.com/en/RandomMusings/javascript/
*/
class Alea {
private $s0;
private $s1;
private $s2;
private $c;
private $args;
/**
* Create a new pseudo-random number generator.
* @param mixed ...$args Seeds for the PRNG. Can be anything which can be
* converted to a string with 'strval'.
*/
public function __construct( ...$args ) {
// Johannes Baagøe <baagoe@baagoe.com>, 2010
$s0 = 0;
$s1 = 0;
$s2 = 0;
$c = 1;
if ( count( $args ) == 0 ) {
$args = [ gettimeofday( true ) ];
}
$mash = new Mash();
$s0 = $mash->mash( ' ' );
$s1 = $mash->mash( ' ' );
$s2 = $mash->mash( ' ' );
foreach ( $args as $a ) {
$s0 -= $mash->mash( $a );
if ( $s0 < 0 ) {
$s0 += 1;
}
$s1 -= $mash->mash( $a );
if ( $s1 < 0 ) {
$s1 += 1;
}
$s2 -= $mash->mash( $a );
if ( $s2 < 0 ) {
$s2 += 1;
}
}
$this->s0 = $s0;
$this->s1 = $s1;
$this->s2 = $s2;
$this->c = $c;
$this->args = $args;
}
/**
* Get a float with 32 bits of randomness.
* @return float
*/
public function random(): float {
$t = 2091639 * $this->s0 + $this->c * 2.3283064365386963e-10; // 2^-32
$this->s0 = $this->s1;
$this->s1 = $this->s2;
$this->c = (int)$t;
$this->s2 = $t - ( $this->c );
return $this->s2;
}
/**
* Get a random 32-bit unsigned integer.
* @return int
*/
public function uint32(): int {
return intval( $this->random() * 0x100000000 ); // 2^32
}
/**
* Get a float with the full 53 bits of randomness.
* @return float
*/
public function fract53(): float {
return $this->random() +
// Using `| 0` to get a truncating conversion to int32 is
// unconventional, but perfectly legit.
// @phan-suppress-next-line PhanTypeInvalidBitwiseBinaryOperator,PhanTypeInvalidLeftOperandOfBitwiseOp
( $this->random() * 0x200000 | 0 ) * 1.1102230246251565e-16; // 2^-53
}
public static function version(): string {
return 'Alea 1.0';
}
public function args(): array {
return $this->args;
}
// coverslide's additions to sync state between two generators
/**
* @return array The exported state of this PRNG.
*/
public function exportState(): array {
return [ $this->s0, $this->s1, $this->s2, $this->c ];
}
/**
* @param array $i The exported state of some other Alea PRNG.
*/
public function importState( array $i ): void {
$this->s0 = $i[ 0 ];
$this->s1 = $i[ 1 ];
$this->s2 = $i[ 2 ];
$this->c = $i[ 3 ];
}
/**
* Create a new generator synced with some exported state.
*
* @param array $i The exported state of some other Alea PRNG.
* @return Alea a new Alea PRNG.
*/
public static function createWithState( array $i ): Alea {
$random = new Alea();
$random->importState( $i );
return $random;
}
}

File Metadata

Mime Type
text/x-php
Expires
Fri, Jul 3, 17:22 (10 h, 37 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
02/c8/c98068d26096a8cf28e22ade25db
Default Alt Text
Alea.php (3 KB)

Event Timeline