1*8462SApril.Chin@Sun.COM /*********************************************************************** 2*8462SApril.Chin@Sun.COM * * 3*8462SApril.Chin@Sun.COM * This software is part of the ast package * 4*8462SApril.Chin@Sun.COM * Copyright (c) 1996-2008 AT&T Intellectual Property * 5*8462SApril.Chin@Sun.COM * and is licensed under the * 6*8462SApril.Chin@Sun.COM * Common Public License, Version 1.0 * 7*8462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 8*8462SApril.Chin@Sun.COM * * 9*8462SApril.Chin@Sun.COM * A copy of the License is available at * 10*8462SApril.Chin@Sun.COM * http://www.opensource.org/licenses/cpl1.0.txt * 11*8462SApril.Chin@Sun.COM * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*8462SApril.Chin@Sun.COM * * 13*8462SApril.Chin@Sun.COM * Information and Software Systems Research * 14*8462SApril.Chin@Sun.COM * AT&T Research * 15*8462SApril.Chin@Sun.COM * Florham Park NJ * 16*8462SApril.Chin@Sun.COM * * 17*8462SApril.Chin@Sun.COM * Glenn Fowler <gsf@research.att.com> * 18*8462SApril.Chin@Sun.COM * * 19*8462SApril.Chin@Sun.COM ***********************************************************************/ 20*8462SApril.Chin@Sun.COM #pragma prototyped 21*8462SApril.Chin@Sun.COM 22*8462SApril.Chin@Sun.COM /* 23*8462SApril.Chin@Sun.COM * prng 24*8462SApril.Chin@Sun.COM */ 25*8462SApril.Chin@Sun.COM 26*8462SApril.Chin@Sun.COM #include <fnv.h> 27*8462SApril.Chin@Sun.COM 28*8462SApril.Chin@Sun.COM #define prng_description \ 29*8462SApril.Chin@Sun.COM "32 bit PRNG (pseudo random number generator) hash." 30*8462SApril.Chin@Sun.COM #define prng_options "\ 31*8462SApril.Chin@Sun.COM [+mpy?The 32 bit PRNG multiplier.]:[number:=0x01000193]\ 32*8462SApril.Chin@Sun.COM [+add?The 32 bit PRNG addend.]:[number:=0]\ 33*8462SApril.Chin@Sun.COM [+init?The PRNG initial value. 0xffffffff is used if \anumber\a is omitted.]:?[number:=0x811c9dc5]\ 34*8462SApril.Chin@Sun.COM " 35*8462SApril.Chin@Sun.COM #define prng_match "prng" 36*8462SApril.Chin@Sun.COM #define prng_done long_done 37*8462SApril.Chin@Sun.COM #define prng_print long_print 38*8462SApril.Chin@Sun.COM #define prng_data long_data 39*8462SApril.Chin@Sun.COM #define prng_scale 0 40*8462SApril.Chin@Sun.COM 41*8462SApril.Chin@Sun.COM typedef uint32_t Prngnum_t; 42*8462SApril.Chin@Sun.COM 43*8462SApril.Chin@Sun.COM typedef struct Prng_s 44*8462SApril.Chin@Sun.COM { 45*8462SApril.Chin@Sun.COM _SUM_PUBLIC_ 46*8462SApril.Chin@Sun.COM _SUM_PRIVATE_ 47*8462SApril.Chin@Sun.COM _INTEGRAL_PRIVATE_ 48*8462SApril.Chin@Sun.COM Prngnum_t init; 49*8462SApril.Chin@Sun.COM Prngnum_t mpy; 50*8462SApril.Chin@Sun.COM Prngnum_t add; 51*8462SApril.Chin@Sun.COM } Prng_t; 52*8462SApril.Chin@Sun.COM 53*8462SApril.Chin@Sun.COM static Sum_t* 54*8462SApril.Chin@Sun.COM prng_open(const Method_t* method, const char* name) 55*8462SApril.Chin@Sun.COM { 56*8462SApril.Chin@Sun.COM register Prng_t* sum; 57*8462SApril.Chin@Sun.COM register const char* s; 58*8462SApril.Chin@Sun.COM register const char* t; 59*8462SApril.Chin@Sun.COM register const char* v; 60*8462SApril.Chin@Sun.COM register int i; 61*8462SApril.Chin@Sun.COM 62*8462SApril.Chin@Sun.COM if (sum = newof(0, Prng_t, 1, 0)) 63*8462SApril.Chin@Sun.COM { 64*8462SApril.Chin@Sun.COM sum->method = (Method_t*)method; 65*8462SApril.Chin@Sun.COM sum->name = name; 66*8462SApril.Chin@Sun.COM } 67*8462SApril.Chin@Sun.COM s = name; 68*8462SApril.Chin@Sun.COM while (*(t = s)) 69*8462SApril.Chin@Sun.COM { 70*8462SApril.Chin@Sun.COM for (t = s, v = 0; *s && *s != '-'; s++) 71*8462SApril.Chin@Sun.COM if (*s == '=' && !v) 72*8462SApril.Chin@Sun.COM v = s; 73*8462SApril.Chin@Sun.COM i = (v ? v : s) - t; 74*8462SApril.Chin@Sun.COM if (isdigit(*t) || v && strneq(t, "mpy", i) && (t = v + 1)) 75*8462SApril.Chin@Sun.COM sum->mpy = strtoul(t, NiL, 0); 76*8462SApril.Chin@Sun.COM else if (strneq(t, "add", i)) 77*8462SApril.Chin@Sun.COM sum->add = v ? strtoul(v + 1, NiL, 0) : ~sum->add; 78*8462SApril.Chin@Sun.COM else if (strneq(t, "init", i)) 79*8462SApril.Chin@Sun.COM sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init; 80*8462SApril.Chin@Sun.COM if (*s == '-') 81*8462SApril.Chin@Sun.COM s++; 82*8462SApril.Chin@Sun.COM } 83*8462SApril.Chin@Sun.COM if (!sum->mpy) 84*8462SApril.Chin@Sun.COM { 85*8462SApril.Chin@Sun.COM sum->mpy = FNV_MULT; 86*8462SApril.Chin@Sun.COM if (!sum->init) 87*8462SApril.Chin@Sun.COM sum->init = FNV_INIT; 88*8462SApril.Chin@Sun.COM } 89*8462SApril.Chin@Sun.COM return (Sum_t*)sum; 90*8462SApril.Chin@Sun.COM } 91*8462SApril.Chin@Sun.COM 92*8462SApril.Chin@Sun.COM static int 93*8462SApril.Chin@Sun.COM prng_init(Sum_t* p) 94*8462SApril.Chin@Sun.COM { 95*8462SApril.Chin@Sun.COM Prng_t* sum = (Prng_t*)p; 96*8462SApril.Chin@Sun.COM 97*8462SApril.Chin@Sun.COM sum->sum = sum->init; 98*8462SApril.Chin@Sun.COM return 0; 99*8462SApril.Chin@Sun.COM } 100*8462SApril.Chin@Sun.COM 101*8462SApril.Chin@Sun.COM static int 102*8462SApril.Chin@Sun.COM prng_block(Sum_t* p, const void* s, size_t n) 103*8462SApril.Chin@Sun.COM { 104*8462SApril.Chin@Sun.COM Prng_t* sum = (Prng_t*)p; 105*8462SApril.Chin@Sun.COM register Prngnum_t c = sum->sum; 106*8462SApril.Chin@Sun.COM register unsigned char* b = (unsigned char*)s; 107*8462SApril.Chin@Sun.COM register unsigned char* e = b + n; 108*8462SApril.Chin@Sun.COM 109*8462SApril.Chin@Sun.COM while (b < e) 110*8462SApril.Chin@Sun.COM c = c * sum->mpy + sum->add + *b++; 111*8462SApril.Chin@Sun.COM sum->sum = c; 112*8462SApril.Chin@Sun.COM return 0; 113*8462SApril.Chin@Sun.COM } 114