lintian doesn't like orphan packages with uploaders...
[debian/amanda] / common-src / simpleprng.c
1 /*
2  * Copyright (c) 2008-2012 Zmanda, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17  *
18  * Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300
19  * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
20  */
21
22 #include "amanda.h"
23 #include "simpleprng.h"
24
25 /* A *very* basic linear congruential generator; values are as cited in
26  * http://en.wikipedia.org/wiki/Linear_congruential_generator for Numerical Recipes */
27
28 #define A 1664525
29 #define C 1013904223
30
31 void
32 simpleprng_seed(
33     simpleprng_state_t *state,
34     guint32 seed)
35 {
36     g_assert(seed != 0);
37     state->val = seed;
38     state->count = 0;
39 }
40
41 guint32
42 simpleprng_get_seed(
43     simpleprng_state_t *state)
44 {
45     return state->val;
46 }
47
48 guint32 simpleprng_rand(
49     simpleprng_state_t *state)
50 {
51     state->count++;
52     return (state->val = (A * state->val) + C);
53 }
54
55 void simpleprng_fill_buffer(
56     simpleprng_state_t *state,
57     gpointer buf,
58     size_t len)
59 {
60     guint8 *p = buf;
61     while (len--) {
62         *(p++) = simpleprng_rand_byte(state);
63     }
64 }
65
66 static char *
67 hexstr(guint8 *p, int len)
68 {
69     char *result = NULL;
70     int i;
71
72     for (i = 0; i < len; i++) {
73         if (result)
74             result = newvstrallocf(result, "%s %02x", result, (guint)(*(p++)));
75         else
76             result = vstrallocf("[%02x", (guint)(*(p++)));
77     }
78     result = newvstrallocf(result, "%s]", result);
79
80     return result;
81 }
82
83 gboolean simpleprng_verify_buffer(
84     simpleprng_state_t *state,
85     gpointer buf,
86     size_t len)
87 {
88     guint8 *p = buf;
89     while (len--) {
90         guint64 count = state->count;
91         guint8 expected = simpleprng_rand_byte(state);
92         guint8 got = *p;
93         if (expected != got) {
94             int remaining = MIN(len, 16);
95             guint8 expbytes[16] = { expected };
96             char *gotstr = hexstr(p, remaining);
97             char *expstr;
98             int i;
99
100             for (i = 1; i < remaining; i++)
101                 expbytes[i] = simpleprng_rand_byte(state);
102             expstr = hexstr(expbytes, remaining);
103
104             g_fprintf(stderr,
105                     "random value mismatch at offset %ju: got %s, expected %s\n",
106                     (uintmax_t)count, gotstr, expstr);
107             g_free(gotstr);
108             return FALSE;
109         }
110         p++;
111     }
112
113     return TRUE;
114 }