7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/***********************************************************************
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1996-2010 AT&T Intellectual Property *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* and is licensed under the *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* A copy of the License is available at *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* http://www.opensource.org/licenses/cpl1.0.txt *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Information and Software Systems Research *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* AT&T Research *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Florham Park NJ *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* Glenn Fowler <gsf@research.att.com> *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin***********************************************************************/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#pragma prototyped
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * prng
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#include <fnv.h>
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define prng_description \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin "32 bit PRNG (pseudo random number generator) hash."
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define prng_options "\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+mpy?The 32 bit PRNG multiplier.]:[number:=0x01000193]\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+add?The 32 bit PRNG addend.]:[number:=0]\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+init?The PRNG initial value. 0xffffffff is used if \anumber\a is omitted.]:?[number:=0x811c9dc5]\
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define prng_match "prng"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define prng_done long_done
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define prng_print long_print
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define prng_data long_data
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define prng_scale 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef uint32_t Prngnum_t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypedef struct Prng_s
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _SUM_PUBLIC_
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _SUM_PRIVATE_
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _INTEGRAL_PRIVATE_
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Prngnum_t init;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Prngnum_t mpy;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Prngnum_t add;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin} Prng_t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Sum_t*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinprng_open(const Method_t* method, const char* name)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Prng_t* sum;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register const char* s;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register const char* t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register const char* v;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int i;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (sum = newof(0, Prng_t, 1, 0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sum->method = (Method_t*)method;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sum->name = name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s = name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (*(t = s))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (t = s, v = 0; *s && *s != '-'; s++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (*s == '=' && !v)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin v = s;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin i = (v ? v : s) - t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (isdigit(*t) || v && strneq(t, "mpy", i) && (t = v + 1))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sum->mpy = strtoul(t, NiL, 0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (strneq(t, "add", i))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sum->add = v ? strtoul(v + 1, NiL, 0) : ~sum->add;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (strneq(t, "init", i))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (*s == '-')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin s++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!sum->mpy)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sum->mpy = FNV_MULT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (!sum->init)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sum->init = FNV_INIT;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return (Sum_t*)sum;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinprng_init(Sum_t* p)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Prng_t* sum = (Prng_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sum->sum = sum->init;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinprng_block(Sum_t* p, const void* s, size_t n)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Prng_t* sum = (Prng_t*)p;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Prngnum_t c = sum->sum;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register unsigned char* b = (unsigned char*)s;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register unsigned char* e = b + n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (b < e)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = c * sum->mpy + sum->add + *b++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sum->sum = c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}