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