4

I would like to create a fast lightweight function in C language that returns a pseudo random unsigned char. The challenging part for me (an ANSI C programmer)is that I cannot use the <stdio.h> or any other ready made functions. Any suggestions..?

by "fast" I meant: avoid unnecessary code (Eg if statements, loops etc) by "lightweight" I meant: use as less variables as possible

thanks

nonouco
  • 1,170
  • 1
  • 13
  • 25

4 Answers4

5

From the linux kernel source code (random32.c)

the values in rnd_state should be initialized like: s1 > 1, s2 > 7, s3 > 15.

The paper claims this is a maximally equidistributed combined Tausworthe generator based on code from GNU Scientific Library 1.5 (30 Jun 2004)

struct rnd_state {
    u32 s1, s2, s3;
};

static u32 __random32(struct rnd_state *state)
{
#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)

    state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
    state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
    state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);

    return (state->s1 ^ state->s2 ^ state->s3);
}

Academia: http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps

Vinicius Kamakura
  • 7,665
  • 1
  • 29
  • 43
5

Use a Linear Congruential Generator

E.g.

uint32_t state = 777;

char myRand()
{
   state = state * 1664525 + 1013904223;
   return state >> 24;
}

Note that myRand returns the high bits, they are more pseudo-random than the low bits.

Linear Congruence Generators were introduced by D. H. Lehmer in 1949 (see Proc. 2nd Symp. on Large-Scale Digital Calculating Machinery (Cambridge, Mass.: Harvard University Press, 1951), 141-146). The concrete numeric constants I gave seem to originate from Press, William H.; et al. (1992). Numerical Recipes in Fortran 77: The Art of Scientific Computing (2nd ed.). ISBN 978-0-521-43064-7.

Peter G.
  • 14,786
  • 7
  • 57
  • 75
  • 1
    -1: LCGs are not all that random and should not be recommended for new applications. – zwol Jun 20 '11 at 20:46
  • 1
    I understood the OP that he wants a solution as simple as possible. No deterministic generator is random anyway. – Peter G. Jun 20 '11 at 20:49
  • If the OP's requirements rule out anything better than a LCRNG then they are in error. – zwol Jun 20 '11 at 20:53
  • 5
    Perhaps he wants to generate simple, low-grade 8-bit audio noise, who am I to know? An LCG as a reasonable choice for this. – Peter G. Jun 20 '11 at 22:25
  • It would be fair to say that this code is coutersy of Knuth, as seen in Numerical Recipes in C, second edition, page 284. – Matěj Štágl Aug 24 '20 at 05:41
  • I checked my copy of Knuth, Seminumerical Algorithms. The code with the given constants, or even the constants alone are not there. Everything in the code besides the choice of constants is trivial, once the LCG scheme is given. I now added a note about its introduction by D.H. Lehmer in 1949 and about the presumed source of the constants I gave. – Peter G. Aug 26 '20 at 11:20
3

Inventing your own random number generator is a bad idea of the same class as inventing your own cryptography: it is easy to construct something that appears to do the job but is in fact disastrously ineffective; constructing something that actually does do the job is much harder. Read the cautionary tale of RANDU, then download one of the variants of the Mersenne Twister and use that.

zwol
  • 135,547
  • 38
  • 252
  • 361
  • 1
    2.5KB of internal state is lightweight in any modern environment but for the most deeply embedded, and the MT folks now also offer [TinyMT](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html) which needs only 127 bits of internal state and is still better than any LCRNG. – zwol Jun 20 '11 at 20:51
  • This is one of the times where the OP wants something they shouldn't. If an OP asked for advice with their implementation of RC4, would you give it to them? – zwol Jun 20 '11 at 20:56
  • how can you know he is not using a microcontroller? – Vinicius Kamakura Jun 20 '11 at 21:00
  • He can still use TinyMT, or the Tausworthe generator you suggested, in that case. Really, the only axes I'm trying to grind here are "nobody should use LCRNGs anymore" and "don't try to reinvent this wheel". – zwol Jun 20 '11 at 21:56
  • ok hexa got the point, and I thought I should reinvent a wheel that has been built a long time ago. I really don't know TINYMC but I will look it up. thx – nonouco Jun 20 '11 at 22:28
  • but seriously, that RNG i suggested is pretty cool :D the linux kernel use it, why shouldn't you? :P – Vinicius Kamakura Jun 20 '11 at 22:44
  • @Zack: Offtopic, but on the subject of RC4, check the cipher suite in use next time you connect to a large site with SSL... – caf Jun 21 '11 at 02:07
1

There's a whole list of pseudo-random number generators at Wikipedia: http://en.wikipedia.org/wiki/List_of_pseudorandom_number_generators

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622