1: /*
2: * Very simple prng to allow for randomized tests with reproducable
3: * results.
4: *
5: * Copyright (C) 2012 by Open Source Routing.
6: * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
7: *
8: * This file is part of Quagga
9: *
10: * Quagga is free software; you can redistribute it and/or modify it
11: * under the terms of the GNU General Public License as published by the
12: * Free Software Foundation; either version 2, or (at your option) any
13: * later version.
14: *
15: * Quagga is distributed in the hope that it will be useful, but
16: * WITHOUT ANY WARRANTY; without even the implied warranty of
17: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18: * General Public License for more details.
19: *
20: * You should have received a copy of the GNU General Public License
21: * along with Quagga; see the file COPYING. If not, write to the Free
22: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23: * 02111-1307, USA.
24: */
25:
26: #include <zebra.h>
27:
28: #include <assert.h>
29: #include <stdlib.h>
30: #include <string.h>
31:
32: #include "prng.h"
33:
34: struct prng
35: {
36: unsigned long long state1;
37: unsigned long long state2;
38: };
39:
40: static char
41: prng_bit(struct prng *prng)
42: {
43: prng->state1 *= 2416;
44: prng->state1 += 374441;
45: prng->state1 %= 1771875;
46:
47: if (prng->state1 % 2)
48: {
49: prng->state2 *= 84589;
50: prng->state2 += 45989;
51: prng->state2 %= 217728;
52: }
53:
54: return prng->state2 % 2;
55: }
56:
57: struct prng*
58: prng_new(unsigned long long seed)
59: {
60: struct prng *rv = calloc(sizeof(*rv), 1);
61: assert(rv);
62:
63: rv->state1 = rv->state2 = seed;
64:
65: return rv;
66: }
67:
68: unsigned int
69: prng_rand(struct prng *prng)
70: {
71: unsigned int i, rv = 0;
72:
73: for (i = 0; i < 32; i++)
74: {
75: rv |= prng_bit(prng);
76: rv <<= 1;
77: }
78: return rv;
79: }
80:
81: const char *
82: prng_fuzz(struct prng *prng,
83: const char *string,
84: const char *charset,
85: unsigned int operations)
86: {
87: static char buf[256];
88: unsigned int charset_len;
89: unsigned int i;
90: unsigned int offset;
91: unsigned int op;
92: unsigned int character;
93:
94: assert(strlen(string) < sizeof(buf));
95:
96: strncpy(buf, string, sizeof(buf));
97: charset_len = strlen(charset);
98:
99: for (i = 0; i < operations; i++)
100: {
101: offset = prng_rand(prng) % strlen(buf);
102: op = prng_rand(prng) % 3;
103:
104: switch (op)
105: {
106: case 0:
107: /* replace */
108: character = prng_rand(prng) % charset_len;
109: buf[offset] = charset[character];
110: break;
111: case 1:
112: /* remove */
113: memmove(buf + offset, buf + offset + 1, strlen(buf) - offset);
114: break;
115: case 2:
116: /* insert */
117: assert(strlen(buf) + 1 < sizeof(buf));
118:
119: memmove(buf + offset + 1, buf + offset, strlen(buf) + 1 - offset);
120: character = prng_rand(prng) % charset_len;
121: buf[offset] = charset[character];
122: break;
123: }
124: }
125: return buf;
126: }
127:
128: void
129: prng_free(struct prng *prng)
130: {
131: free(prng);
132: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>