17c2fbfb3SApril Chin /***********************************************************************
27c2fbfb3SApril Chin * *
37c2fbfb3SApril Chin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1996-2010 AT&T Intellectual Property *
57c2fbfb3SApril Chin * and is licensed under the *
67c2fbfb3SApril Chin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
87c2fbfb3SApril Chin * *
97c2fbfb3SApril Chin * A copy of the License is available at *
107c2fbfb3SApril Chin * http://www.opensource.org/licenses/cpl1.0.txt *
117c2fbfb3SApril Chin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
127c2fbfb3SApril Chin * *
137c2fbfb3SApril Chin * Information and Software Systems Research *
147c2fbfb3SApril Chin * AT&T Research *
157c2fbfb3SApril Chin * Florham Park NJ *
167c2fbfb3SApril Chin * *
177c2fbfb3SApril Chin * Glenn Fowler <gsf@research.att.com> *
187c2fbfb3SApril Chin * *
197c2fbfb3SApril Chin ***********************************************************************/
207c2fbfb3SApril Chin #pragma prototyped
217c2fbfb3SApril Chin
227c2fbfb3SApril Chin /*
237c2fbfb3SApril Chin * prng
247c2fbfb3SApril Chin */
257c2fbfb3SApril Chin
267c2fbfb3SApril Chin #include <fnv.h>
277c2fbfb3SApril Chin
287c2fbfb3SApril Chin #define prng_description \
297c2fbfb3SApril Chin "32 bit PRNG (pseudo random number generator) hash."
307c2fbfb3SApril Chin #define prng_options "\
317c2fbfb3SApril Chin [+mpy?The 32 bit PRNG multiplier.]:[number:=0x01000193]\
327c2fbfb3SApril Chin [+add?The 32 bit PRNG addend.]:[number:=0]\
337c2fbfb3SApril Chin [+init?The PRNG initial value. 0xffffffff is used if \anumber\a is omitted.]:?[number:=0x811c9dc5]\
347c2fbfb3SApril Chin "
357c2fbfb3SApril Chin #define prng_match "prng"
367c2fbfb3SApril Chin #define prng_done long_done
377c2fbfb3SApril Chin #define prng_print long_print
387c2fbfb3SApril Chin #define prng_data long_data
397c2fbfb3SApril Chin #define prng_scale 0
407c2fbfb3SApril Chin
417c2fbfb3SApril Chin typedef uint32_t Prngnum_t;
427c2fbfb3SApril Chin
437c2fbfb3SApril Chin typedef struct Prng_s
447c2fbfb3SApril Chin {
457c2fbfb3SApril Chin _SUM_PUBLIC_
467c2fbfb3SApril Chin _SUM_PRIVATE_
477c2fbfb3SApril Chin _INTEGRAL_PRIVATE_
487c2fbfb3SApril Chin Prngnum_t init;
497c2fbfb3SApril Chin Prngnum_t mpy;
507c2fbfb3SApril Chin Prngnum_t add;
517c2fbfb3SApril Chin } Prng_t;
527c2fbfb3SApril Chin
537c2fbfb3SApril Chin static Sum_t*
prng_open(const Method_t * method,const char * name)547c2fbfb3SApril Chin prng_open(const Method_t* method, const char* name)
557c2fbfb3SApril Chin {
567c2fbfb3SApril Chin register Prng_t* sum;
577c2fbfb3SApril Chin register const char* s;
587c2fbfb3SApril Chin register const char* t;
597c2fbfb3SApril Chin register const char* v;
607c2fbfb3SApril Chin register int i;
617c2fbfb3SApril Chin
627c2fbfb3SApril Chin if (sum = newof(0, Prng_t, 1, 0))
637c2fbfb3SApril Chin {
647c2fbfb3SApril Chin sum->method = (Method_t*)method;
657c2fbfb3SApril Chin sum->name = name;
667c2fbfb3SApril Chin }
677c2fbfb3SApril Chin s = name;
687c2fbfb3SApril Chin while (*(t = s))
697c2fbfb3SApril Chin {
707c2fbfb3SApril Chin for (t = s, v = 0; *s && *s != '-'; s++)
717c2fbfb3SApril Chin if (*s == '=' && !v)
727c2fbfb3SApril Chin v = s;
737c2fbfb3SApril Chin i = (v ? v : s) - t;
747c2fbfb3SApril Chin if (isdigit(*t) || v && strneq(t, "mpy", i) && (t = v + 1))
757c2fbfb3SApril Chin sum->mpy = strtoul(t, NiL, 0);
767c2fbfb3SApril Chin else if (strneq(t, "add", i))
777c2fbfb3SApril Chin sum->add = v ? strtoul(v + 1, NiL, 0) : ~sum->add;
787c2fbfb3SApril Chin else if (strneq(t, "init", i))
797c2fbfb3SApril Chin sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init;
807c2fbfb3SApril Chin if (*s == '-')
817c2fbfb3SApril Chin s++;
827c2fbfb3SApril Chin }
837c2fbfb3SApril Chin if (!sum->mpy)
847c2fbfb3SApril Chin {
857c2fbfb3SApril Chin sum->mpy = FNV_MULT;
867c2fbfb3SApril Chin if (!sum->init)
877c2fbfb3SApril Chin sum->init = FNV_INIT;
887c2fbfb3SApril Chin }
897c2fbfb3SApril Chin return (Sum_t*)sum;
907c2fbfb3SApril Chin }
917c2fbfb3SApril Chin
927c2fbfb3SApril Chin static int
prng_init(Sum_t * p)937c2fbfb3SApril Chin prng_init(Sum_t* p)
947c2fbfb3SApril Chin {
957c2fbfb3SApril Chin Prng_t* sum = (Prng_t*)p;
967c2fbfb3SApril Chin
977c2fbfb3SApril Chin sum->sum = sum->init;
987c2fbfb3SApril Chin return 0;
997c2fbfb3SApril Chin }
1007c2fbfb3SApril Chin
1017c2fbfb3SApril Chin static int
prng_block(Sum_t * p,const void * s,size_t n)1027c2fbfb3SApril Chin prng_block(Sum_t* p, const void* s, size_t n)
1037c2fbfb3SApril Chin {
1047c2fbfb3SApril Chin Prng_t* sum = (Prng_t*)p;
1057c2fbfb3SApril Chin register Prngnum_t c = sum->sum;
1067c2fbfb3SApril Chin register unsigned char* b = (unsigned char*)s;
1077c2fbfb3SApril Chin register unsigned char* e = b + n;
1087c2fbfb3SApril Chin
1097c2fbfb3SApril Chin while (b < e)
1107c2fbfb3SApril Chin c = c * sum->mpy + sum->add + *b++;
1117c2fbfb3SApril Chin sum->sum = c;
1127c2fbfb3SApril Chin return 0;
1137c2fbfb3SApril Chin }
114