Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Pseudo-Random Algorithm

I'm need a pseudo-random generator which takes a number as input and returns another number witch is reproducible and seems to be random.

  • Each input number should match to exactly one output number and vice versa
  • same input numbers always result in same output numbers
  • sequential input numbers that are close together (eg. 1 and 2) should produce completely different output numbers (eg. 1 => 9783526, 2 => 283)

It must not be perfect, it's just to create random but reproducible test data.

I use C#.


I wrote this funny piece of code some time ago which produced something random.

  public static long Scramble(long number, long max) 
  {
    // some random values 
    long[] scramblers = { 3, 5, 7, 31, 343, 2348, 89897 };
    number += (max / 7) + 6;
    number %= max;
    // shuffle according to divisibility
    foreach (long scrambler in scramblers) 
    {
      if (scrambler >= max / 3) break;
      number = ((number * scrambler) % max) 
        + ((number * scrambler) / max);
    }

    return number % max;
  }

I would like to have something better, more reliable, working with any size of number (no max argument).

Could this probably be solved using a CRC algorithm? Or some bit shuffling stuff.

like image 218
Stefan Steinegger Avatar asked Oct 08 '09 13:10

Stefan Steinegger


3 Answers

I remove the microsoft code from this answer, the GNU code file is a lot longer but basically it contains this from http://cs.uccs.edu/~cs591/bufferOverflow/glibc-2.2.4/stdlib/random_r.c :

int32_t val = state[0];
val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
state[0] = val;
*result = val;

for your purpose, the seed is state[0] so it would look more like

int getRand(int val)
{
    return ((val * 1103515245) + 12345) & 0x7fffffff;
}
like image 62
John Boker Avatar answered Sep 21 '22 06:09

John Boker


You (maybe) can do this easily in C# using the Random class:

public int GetPseudoRandomNumber(int input)
{
    Random random = new Random(input);
    return random.Next();
}

Since you're explicitly seeding Random with the input, you will get the same output every time given the same input value.

like image 45
MusiGenesis Avatar answered Sep 20 '22 06:09

MusiGenesis


A tausworthe generator is simple to implement and pretty fast. The following pseudocode implementation has full cycle (2**31 - 1, because zero is a fixed point):

def tausworthe(seed)
  seed ^= seed >> 13
  seed ^= seed << 18
  return seed & 0x7fffffff

I don't know C#, but I'm assuming it has XOR (^) and bit shift (<<, >>) operators as in C.

Set an initial seed value, and invoke with seed = tausworthe(seed).

like image 45
pjs Avatar answered Sep 23 '22 06:09

pjs