C language Generation 32-bit and 64-bit random number algorithm
/*** randstd.h** standard definitions and types, Bob jenkins** 2015-01-19:revised by cheungmine*/#ifndef _randstd_h__#d Efine _randstd_h__#ifndef stdio# include <stdio.h># define STDIO#ENDIF#IFNDEF stddef# include <stddef.h># Define Stddef#endiftypedef unsigned long long ub8; #define Ub8maxval 0xffffffffffffffffll#define Ub8bits 64typedef signed Long long sb8; #define SB8MAXVAL 0x7ffffffffffffffflltypedef unsigned long int ub4; /* Unsigned 4-byte quantities */#define UB4MAXVAL 0xfffffffftypedef signed long int sb4; #define Ub4bits 32#define Sb4maxva L 0x7ffffffftypedef unsigned short int ub2, #define UB2MAXVAL 0xffff#define ub2bits 16typedef signed short int sb2; #define Sb2maxval 0x7fff/* unsigned 1-byte quantities */typedef unsigned char ub1; #define UB1MAXVAL 0xff#define Ub1bits 8/* signed 1-byte Quantities */typedef signed char sb1; #define SB1MAXVAL 0x7f/* fastest type available */typedef int word; #define Bi S (target,mask) ((target) |= (mask)) #define BIC (Target,mask) (target) &= ~ (mask)) #define BIT (Target,mask) ((target) & (mask) #ifndef min# define min (b) ((a) < (a))? (a): (b) #endif/* min */#ifndef max# define MAX (b) ((a) < (c))? (b): (a) #endif/* Max */#ifndef abs# define ABS (a) (((a) >0)? (a):-(a) #endif #ifndef align# define align (a) (((UB4) A + (sizeof (void *)-1) & (~ (sizeof (void *)-1)) #endif/* Align * #define RAND_TRUE 1#define rand_false 0#define rand_success 0/* 1 on VAX */#endif/* _randstd_h__ *
/*** rand.h* definitions for a random number generator*-------------------------------------------------------------- ---------------* by Bob Jenkins, 1996, Public domain* modified:* 960327:creation (addition of randinit, really) * 9707 19:use context, not global variables, for internal state* 980324:renamed seed to flag* 980605:recommend randsizl=4 For noncryptography.* 010626:note domain*------------------------------------------------------------ -----------------* * 2015-01-19:revised by cheungmine*/#ifndef _rand_h__#define _rand_h__#ifdef __cplusplusextern "C" { #endif include "Randstd.h" #define RANDSIZL (8) #define RANDSIZ (1<<RANDSIZL)/*** context of random number genera Tor*/struct randctx_ub4{ub4 randcnt; Ub4 Seed[randsiz]; Ub4 Mm[randsiz]; UB4 AA; UB4 BB; Ub4 cc;}; typedef struct RANDCTX_UB4 randctx;/*** context of random number generator for 64-bits int*/struct randctx_ub8{UB8 R andcnt; UB8 Seed[randsiz];UB8 Mm[randsiz]; UB8 AA; UB8 BB; UB8 cc;}; typedef struct RANDCTX_UB8 randctx64;/*** randinit* init rand seed*/extern void Rand_init (Randctx *r, Word time_as_see d); extern void Rand64_init (randctx64 *r, Word time_as_seed);/*** rand* call rand (RANDCTX *) to retrieve a single 32-bit Random Value.*/extern ub4 rand (Randctx *r), extern ub4 Randint (randctx *r, Ub4 rmin, Ub4 rmax), extern ub8 Rand64 (randctx64 *R); extern ub8 Randint64 (randctx64 *r, Ub8 rmin, Ub8 rmax); #ifdef __cplusplus} #endif #endif/* _rand_h__ */
/*** rand.c* by Bob Jenkins. My random number generator, ISAAC. Public domain.*-----------------------------------------------------------------------------* modified:* 960327: Creation (addition of randinit, really) * 970719:use context, not global variables, for internal state* 980324:added Main (ifdef ' Ed out), also rearranged Randinit () * 010626:note The This is public domain*------------------------------ -----------------------------------------------* * 2015-01-19:revised by cheungmine*/#include "rand.h" #include < time.h>/***==============================================================================* 32-bits int Random generator*==============================================================================*/#define Isaac_golden_ Ratio32 0x9e3779b9#define ind32 (mm,x) (* (UB4 *) ((UB1 *) (mm) + ((x) & ((RANDSIZ-1) <<2))) #define RNGSTEP32 (Mix, A,B,MM,M,M2,R,X) {x = *m; A = (a^ (mix)) + * (m2++); * (m++) = y = Ind32 (mm,x) + A + B; * (r++) = b = Ind32 (MM,Y>>RANDSIZL) + x; } #define MIX32 (a,b,c,d,e,f,g,h) {a^=b<<11; d+=a; b+=c; b^=c>>2; E+=b; C+=d; c^=d<<8; F+=c; D+=e; d^=e>>16; G+=d; E+=f; e^=f<<10; H+=e; f+=g; f^=g>>4; A+=f; G+=h; g^=h<<8; b+=g; H+=a; h^=a>>9; C+=h; A+=b; }static void Isaac32 (Randctx *ctx) {Register UB4 A, b, X, Y, *m, *mm, *m2, *r, *mend; MM = ctx->mm; r = ctx->seed; A = ctx->aa; b = ctx->bb + (++CTX->CC); for (m = mm, mend = m2 = m+ (RANDSIZ/2); m<mend;) {RNGSTEP32 (a<<13, A, B, mm, M, M2, R, X); RNGSTEP32 (A>>6, A, B, mm, M, M2, R, X); RNGSTEP32 (A<<2, A, B, mm, M, M2, R, X); RNGSTEP32 (A>>16, A, B, mm, M, M2, R, X); } for (m2 = mm; m2<mend;) {RNGSTEP32 (a<<13, A, B, mm, M, M2, R, X); RNGSTEP32 (A>>6, A, B, mm, M, M2, R, X); RNGSTEP32 (A<<2, A, B, mm, M, M2, R, X); RNGSTEP32 (A>>16, A, B, mm, M, M2, R, X); } CTX->BB = b; Ctx->aa = A;} #define GEN_RAND32 (R) (! ( R)->randcnt--? (ISAAC32 (R), (R)->randcnt=randsiz-1, (R)->seed[(r)->randcnt]): (R)->seed[(r)->randcnt]) void rand_i NIT (Randctx *ctx, Word time_as_seed) {word I; Ub4 A, B, C, D, E, F, G, H; Ub4 *m, *r; Ctx->aa = CTX->BB = CTX->CC = 0; m = ctx->mm; r = ctx->seed; A = b = c = d = e = f = g = h = isaac_golden_ratio32; /* The golden ratio */* init seed */for (i=0; i<256; ++i) {R[i] = (UB4) (time_as_seed? Time (0): 0); } for (i=0; i<4; ++i) {/* Scramble it */mix32 (A,B,C,D,E,F,G,H); } if (1) {/* Initialize using the contents of r[] as the seed */for (i=0; i<randsiz; i+=8) { A+=r[i]; B+=R[I+1]; C+=R[I+2]; D+=R[I+3]; E+=R[I+4]; F+=R[I+5]; G+=R[I+6]; H+=R[I+7]; mix32 (a,b,c,d,e,f,g, h); M[i]=a; M[i+1]=b; M[i+2]=c; M[i+3]=d; M[i+4]=e; M[i+5]=f; m[i+6]=g; M[i+7]=h; }/* A second pass to make all of the seed affect all of M */for (i=0; i<randsiz; i+=8) { A+=m[i]; B+=M[I+1]; C+=M[I+2]; D+=M[I+3]; E+=M[I+4]; F+=M[I+5]; G+=M[I+6]; H+=M[I+7]; mix32 (A,B,C,D,E,F,G,H); M[i]=a; M[i+1]=b; M[i+2]=c; M[i+3]=d; M[i+4]=e; M[i+5]=f; m[i+6]=g; M[i+7]=h; }} else {/* never run to This:fill in m[] with messy stuff */for (i=0; i<randsiz; i+=8) { mix32 (A,B,C,D,E,F,G,H); M[i]=a; M[i+1]=b; M[i+2]=c; M[i+3]=d; M[i+4]=e; M[i+5]=f; m[i+6]=g; M[i+7]=h; }} isaac32 (CTX); /* Fill in the first set of results */ctx->randcnt = Randsiz; /* Prepare to use the first set of results */}/*** randint* get 32-bits unsigned integer random*/ub4 rand (Randctx *r) { return gen_rand32 (r);} /*** Randint* get integer random between rmin and Rmax*/ub4 Randint (Randctx *r, Ub4 rmin, Ub4 rmax) {if (! r->randcnt--) { ISAAC32 (R); r->randcnt = RANDSIZ-1; } UB4 ret = (UB4) r->seed[r->randcnt]; return ret% (UB4) (Rmax-rmin + 1) + rmin;} /***==============================================================================* bits int Random generator*== ============================================================================*/#define Isaac_golden_ratio64 0x9e3779b97f4a7c13ll#define ind64 (mm,x) (* (UB8 *) ((UB1 *) (mm) + ((x) & ((RANDSIZ-1) <<3))) #define RNGSTEP64 ( MIX,A,B,MM,M,M2,R,X) {x = *m; A = (mix) + * (m2++); * (m++) = y = Ind64 (mm,x) + A + B; * (r++) = B = Ind64 (MM,Y>>RANDSIZL) + x; } #define MIX64 (a,b,c,d,e,f,g,h) {a-=e; f^=h>>9; H+=a; B-=f; g^=a<<9; A+=b; c-=g; h^=b>>23; B+=c; D-=h; a^=c<<15; C+=d; E-=a; b^=d>>14; D+=e; F-=b; c^=e<<20; E+=f; g-=C d^=f>>17; f+=g; H-=d; e^=g<<14; G+=h; }static void Isaac64 (randctx64 *ctx) {register UB8 a,b,x,y,*m,*mm,*m2,*r,*mend; MM = ctx->mm; r = ctx->seed; A = ctx->aa; b = ctx->bb + (++CTX->CC); for (m = mm, mend = m2 = m+ (RANDSIZ/2); m<mend;) {Rngstep64 (~ (a^ (a<<21)), A, B, mm, M, M2, R, X); Rngstep64 (a^ (a>>5), A, B, mm, M, M2, R, X); Rngstep64 (a^ (a<<12), A, B, mm, M, M2, R, X); Rngstep64 (a^ (a>>33), A, B, mm, M, M2, R, X); } for (m2 = mm; m2<mend;) {Rngstep64 (~ (a^ (a<<21)), A, B, mm, M, M2, R, X); Rngstep64 (a^ (a>>5), A, B, mm, M, M2, R, X); Rngstep64 (a^ (a<<12), A, B, mm, M, M2, R, X); Rngstep64 (a^ (a>>33), A, B, mm, M, M2, R, X); } CTX->BB = b; Ctx->aa = A;} #define GEN_RAND64 (R) (! ( R)->randcnt--? (ISAAC64 (R), (R)->randcnt=randsiz-1, (R)->seed[(r)->randcnt]): (R)seed[(R)->randcnt]) void Rand64_init (randctx64 *ctx, Word time_as_seed) {word I; UB8 a,b,c,d,e,f,g,h; Ub8 *mm, *r; Ctx->aa = CTX->BB = CTX->CC = (ub8) 0; A=b=c=d=e=f=g=h= isaac_golden_ratio64; /* The golden ratio */mm = ctx->mm; r = ctx->seed; /* Init seed */for (i=0; i<256; ++i) {R[i] = (UB8) (time_as_seed? Time (0): 0); } for (i=0; i<4; ++i) {/* Scramble it */mix64 (A,B,C,D,E,F,G,H); } for (i=0; i<randsiz; i+=8) {/* fill in mm[] with messy stuff */if (1) {/* use all the INF Ormation in the seed */a+=r[i]; B+=R[I+1]; C+=R[I+2]; D+=R[I+3]; E+=R[I+4]; F+=R[I+5]; G+=R[I+6]; H+=R[I+7]; } mix64 (A,b,c,d,e,f,g,h); Mm[i]=a; Mm[i+1]=b; Mm[i+2]=c; Mm[i+3]=d; Mm[i+4]=e; Mm[i+5]=f; mm[i+6]=g; Mm[i+7]=h; } if (1) {/* A second pass to make all of the seed affect all of MM */for (i=0; i<randsiz; i+=8) {a+=mm[i]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3]; E+=MM[I+4]; F+=MM[I+5]; G+=MM[I+6]; H+=MM[I+7]; Mix64 (A,B,C,D,E,F,G,H); Mm[i]=a; Mm[i+1]=b; Mm[i+2]=c; Mm[i+3]=d; Mm[i+4]=e; Mm[i+5]=f; mm[i+6]=g; Mm[i+7]=h; }} ISAAC64 (CTX); /* Fill in the first set of results */ctx->randcnt = Randsiz; /* Prepare to use the first set of results */}/*** rand64* get 64-bits unsigned integer random*/ub8 rand64 (randctx64 *r) {return (UB8) (GEN_RAND64 (R));} /*** randint64* get 64-bits unsigned integer random*/ub8 randint64 (randctx64 *r, Ub8 rmin, Ub8 rmax) {if (! R->ran dcnt--) {ISAAC64 (R); r->randcnt = RANDSIZ-1; } UB8 ret = (UB8) r->seed[r->randcnt]; return ret% (UB8) (Rmax-rmin + 1) + rmin;} #ifdef neverstatic void Inner_test32 () {UB4 i,j; Randctx CTX; Rand_init (&ctx, Rand_false); for (i=0; i<2; ++i) {ISAAC32 (&CTX);for (j=0; j<256; ++j) {printf ("%.8lx", Ctx.seed[j]); if ((j&7) ==7) {printf ("\ n"); }}}}static void Inner_test64 () {UB8 i,j; Randctx64 CTX; Rand64_init (&ctx, Rand_false); for (i=0; i<2; ++i) {ISAAC64 (&CTX); for (j=0; j<randsiz; ++j) {printf ("%.8lx%.8lx", (UB4) (ctx.seed[j]>>32), (UB4) ctx.seed[j]); if ((j&3) ==3) {printf ("\ n"); }}}}static void usage () {int i; Randctx CTX; Randctx64 ctx64; Rand_init (&ctx, rand_true); Rand64_init (&ctx64, rand_true); for (i=0; i<100; ++i) {printf ("%03d:%d\n", I, (SB4) Randint (&ctx,-100, 100)); printf ("%03d:%lld\n", I, (SB8) Randint64 (&ctx64,-100, 100)); }}int Main () {inner_test32 (); Inner_test64 (); Usage ();} #endif
C language Generation 32-bit and 64-bit random number algorithm