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