xref: /onnv-gate/usr/src/lib/libsum/common/sum-prng.c (revision 12068:08a39a083754)
18462SApril.Chin@Sun.COM /***********************************************************************
28462SApril.Chin@Sun.COM *                                                                      *
38462SApril.Chin@Sun.COM *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1996-2010 AT&T Intellectual Property          *
58462SApril.Chin@Sun.COM *                      and is licensed under the                       *
68462SApril.Chin@Sun.COM *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
88462SApril.Chin@Sun.COM *                                                                      *
98462SApril.Chin@Sun.COM *                A copy of the License is available at                 *
108462SApril.Chin@Sun.COM *            http://www.opensource.org/licenses/cpl1.0.txt             *
118462SApril.Chin@Sun.COM *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
128462SApril.Chin@Sun.COM *                                                                      *
138462SApril.Chin@Sun.COM *              Information and Software Systems Research               *
148462SApril.Chin@Sun.COM *                            AT&T Research                             *
158462SApril.Chin@Sun.COM *                           Florham Park NJ                            *
168462SApril.Chin@Sun.COM *                                                                      *
178462SApril.Chin@Sun.COM *                 Glenn Fowler <gsf@research.att.com>                  *
188462SApril.Chin@Sun.COM *                                                                      *
198462SApril.Chin@Sun.COM ***********************************************************************/
208462SApril.Chin@Sun.COM #pragma prototyped
218462SApril.Chin@Sun.COM 
228462SApril.Chin@Sun.COM /*
238462SApril.Chin@Sun.COM  * prng
248462SApril.Chin@Sun.COM  */
258462SApril.Chin@Sun.COM 
268462SApril.Chin@Sun.COM #include <fnv.h>
278462SApril.Chin@Sun.COM 
288462SApril.Chin@Sun.COM #define prng_description \
298462SApril.Chin@Sun.COM 	"32 bit PRNG (pseudo random number generator) hash."
308462SApril.Chin@Sun.COM #define prng_options	"\
318462SApril.Chin@Sun.COM [+mpy?The 32 bit PRNG multiplier.]:[number:=0x01000193]\
328462SApril.Chin@Sun.COM [+add?The 32 bit PRNG addend.]:[number:=0]\
338462SApril.Chin@Sun.COM [+init?The PRNG initial value. 0xffffffff is used if \anumber\a is omitted.]:?[number:=0x811c9dc5]\
348462SApril.Chin@Sun.COM "
358462SApril.Chin@Sun.COM #define prng_match	"prng"
368462SApril.Chin@Sun.COM #define prng_done	long_done
378462SApril.Chin@Sun.COM #define prng_print	long_print
388462SApril.Chin@Sun.COM #define prng_data	long_data
398462SApril.Chin@Sun.COM #define prng_scale	0
408462SApril.Chin@Sun.COM 
418462SApril.Chin@Sun.COM typedef uint32_t Prngnum_t;
428462SApril.Chin@Sun.COM 
438462SApril.Chin@Sun.COM typedef struct Prng_s
448462SApril.Chin@Sun.COM {
458462SApril.Chin@Sun.COM 	_SUM_PUBLIC_
468462SApril.Chin@Sun.COM 	_SUM_PRIVATE_
478462SApril.Chin@Sun.COM 	_INTEGRAL_PRIVATE_
488462SApril.Chin@Sun.COM 	Prngnum_t		init;
498462SApril.Chin@Sun.COM 	Prngnum_t		mpy;
508462SApril.Chin@Sun.COM 	Prngnum_t		add;
518462SApril.Chin@Sun.COM } Prng_t;
528462SApril.Chin@Sun.COM 
538462SApril.Chin@Sun.COM static Sum_t*
prng_open(const Method_t * method,const char * name)548462SApril.Chin@Sun.COM prng_open(const Method_t* method, const char* name)
558462SApril.Chin@Sun.COM {
568462SApril.Chin@Sun.COM 	register Prng_t*	sum;
578462SApril.Chin@Sun.COM 	register const char*	s;
588462SApril.Chin@Sun.COM 	register const char*	t;
598462SApril.Chin@Sun.COM 	register const char*	v;
608462SApril.Chin@Sun.COM 	register int		i;
618462SApril.Chin@Sun.COM 
628462SApril.Chin@Sun.COM 	if (sum = newof(0, Prng_t, 1, 0))
638462SApril.Chin@Sun.COM 	{
648462SApril.Chin@Sun.COM 		sum->method = (Method_t*)method;
658462SApril.Chin@Sun.COM 		sum->name = name;
668462SApril.Chin@Sun.COM 	}
678462SApril.Chin@Sun.COM 	s = name;
688462SApril.Chin@Sun.COM 	while (*(t = s))
698462SApril.Chin@Sun.COM 	{
708462SApril.Chin@Sun.COM 		for (t = s, v = 0; *s && *s != '-'; s++)
718462SApril.Chin@Sun.COM 			if (*s == '=' && !v)
728462SApril.Chin@Sun.COM 				v = s;
738462SApril.Chin@Sun.COM 		i = (v ? v : s) - t;
748462SApril.Chin@Sun.COM 		if (isdigit(*t) || v && strneq(t, "mpy", i) && (t = v + 1))
758462SApril.Chin@Sun.COM 			sum->mpy = strtoul(t, NiL, 0);
768462SApril.Chin@Sun.COM 		else if (strneq(t, "add", i))
778462SApril.Chin@Sun.COM 			sum->add = v ? strtoul(v + 1, NiL, 0) : ~sum->add;
788462SApril.Chin@Sun.COM 		else if (strneq(t, "init", i))
798462SApril.Chin@Sun.COM 			sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init;
808462SApril.Chin@Sun.COM 		if (*s == '-')
818462SApril.Chin@Sun.COM 			s++;
828462SApril.Chin@Sun.COM 	}
838462SApril.Chin@Sun.COM 	if (!sum->mpy)
848462SApril.Chin@Sun.COM 	{
858462SApril.Chin@Sun.COM 		sum->mpy = FNV_MULT;
868462SApril.Chin@Sun.COM 		if (!sum->init)
878462SApril.Chin@Sun.COM 			sum->init = FNV_INIT;
888462SApril.Chin@Sun.COM 	}
898462SApril.Chin@Sun.COM 	return (Sum_t*)sum;
908462SApril.Chin@Sun.COM }
918462SApril.Chin@Sun.COM 
928462SApril.Chin@Sun.COM static int
prng_init(Sum_t * p)938462SApril.Chin@Sun.COM prng_init(Sum_t* p)
948462SApril.Chin@Sun.COM {
958462SApril.Chin@Sun.COM 	Prng_t*		sum = (Prng_t*)p;
968462SApril.Chin@Sun.COM 
978462SApril.Chin@Sun.COM 	sum->sum = sum->init;
988462SApril.Chin@Sun.COM 	return 0;
998462SApril.Chin@Sun.COM }
1008462SApril.Chin@Sun.COM 
1018462SApril.Chin@Sun.COM static int
prng_block(Sum_t * p,const void * s,size_t n)1028462SApril.Chin@Sun.COM prng_block(Sum_t* p, const void* s, size_t n)
1038462SApril.Chin@Sun.COM {
1048462SApril.Chin@Sun.COM 	Prng_t*			sum = (Prng_t*)p;
1058462SApril.Chin@Sun.COM 	register Prngnum_t	c = sum->sum;
1068462SApril.Chin@Sun.COM 	register unsigned char*	b = (unsigned char*)s;
1078462SApril.Chin@Sun.COM 	register unsigned char*	e = b + n;
1088462SApril.Chin@Sun.COM 
1098462SApril.Chin@Sun.COM 	while (b < e)
1108462SApril.Chin@Sun.COM 		c = c * sum->mpy + sum->add + *b++;
1118462SApril.Chin@Sun.COM 	sum->sum = c;
1128462SApril.Chin@Sun.COM 	return 0;
1138462SApril.Chin@Sun.COM }
114