Skip to content

Instantly share code, notes, and snippets.

@mauris
Created September 12, 2012 05:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mauris/3704440 to your computer and use it in GitHub Desktop.
Save mauris/3704440 to your computer and use it in GitHub Desktop.
Pseudo Random Number Generation (PRNG) using Trigonometry
<?php
function prng01($min = null, $max = null){
if($min === null){
$min = 0;
}
if($max === null){
$max = PHP_INT_MAX;
}
static $seed = 3;
$epoch = microtime(true) - 1262304000;
$start = microtime(true);
for($i = 0; $i < $epoch; $i+=10000){};
$diff = microtime(true) - $start;
$x = $epoch - $min + ($seed + ($epoch & 1 ? -1 : 1) * $diff);
// 3sin(20x^(6/7)) * 3sin(4x^(3/2))
$value = ((9 * sin(20 * pow($x, 6/7)) * sin(pow($x * 4, 3/2))) + 9) / 18;
++$seed;
return round($value * ($max - $min) + $min);
}
@xeoncross
Copy link

Do you have any references to explain choices about this implementation?

@mauris
Copy link
Author

mauris commented Sep 18, 2012

@xeoncross - To be clear I would say that this is a random-enough but not cryptographically-safe PRNG. The generator relies on four parts:

  1. The epoch time (in microtime float) that is from midnight of 1 Jan 2010 (Fri, 01 Jan 2010 00:00:00 GMT) - the value in $epoch
  2. The microtime taken for the loop to run from 0 to the epoch time calculated in (1) - the value in $diff
  3. The seed that is incremented based on number of function calls (starts with 3 and incremented once each time it is called) - the value in $seed
  4. The trigonometric function that uses sin() to generate the curves.

For first you should take a look at the graph generated by the equation y = 9sin(20x^(6/7)) * sin(4x^(3/2)): Graph generated by FooPlot

You can observe that as the x-value increases, the y-value "randomly" cycles from y=-9 to y=9. Hence we can determine the domain and range of the graph to be:

  • Domain: x > 0
  • Range: -9 <= y <= 9

Using values (1), (2) and (3) we are able to calculate the $x value to be supplied into the trigo function. The y-value returned by the trigo function is then suited into the random number range $min and $max.

@mauris
Copy link
Author

mauris commented Sep 18, 2012

The reason why I chose a trigo-function is because it is easy implementable. As long as X continues to increase, you can't really tell what's next. And it gives a pseudo-random value based on a given value (in this case time). Although it is arguable that given the same time-value the function can to generate the same random number, generating the random value based on multiple factors e.g. the time taken for the execution of iterations, can cause the function to be non-replayable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment