blob: 8d78ea523b9ea09f412bd16f4990dada278f377b [file] [log] [blame]
Christian Frankefa713d92013-07-05 15:35:37 +00001/*
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 <assert.h>
27#include <stdlib.h>
Christian Franke8f399b02013-09-30 12:27:50 +000028#include <string.h>
Christian Frankefa713d92013-07-05 15:35:37 +000029
30#include "prng.h"
31
32struct prng
33{
34 unsigned long long state1;
35 unsigned long long state2;
36};
37
38static char
39prng_bit(struct prng *prng)
40{
41 prng->state1 *= 2416;
42 prng->state1 += 374441;
43 prng->state1 %= 1771875;
44
45 if (prng->state1 % 2)
46 {
47 prng->state2 *= 84589;
48 prng->state2 += 45989;
49 prng->state2 %= 217728;
50 }
51
52 return prng->state2 % 2;
53}
54
55struct prng*
56prng_new(unsigned long long seed)
57{
58 struct prng *rv = calloc(sizeof(*rv), 1);
59 assert(rv);
60
61 rv->state1 = rv->state2 = seed;
62
63 return rv;
64}
65
66unsigned int
67prng_rand(struct prng *prng)
68{
69 unsigned int i, rv = 0;
70
71 for (i = 0; i < 32; i++)
72 {
73 rv |= prng_bit(prng);
74 rv <<= 1;
75 }
76 return rv;
77}
78
Christian Franke8f399b02013-09-30 12:27:50 +000079const char *
80prng_fuzz(struct prng *prng,
81 const char *string,
82 const char *charset,
83 unsigned int operations)
84{
85 static char buf[256];
86 unsigned int charset_len;
87 unsigned int i;
88 unsigned int offset;
89 unsigned int op;
90 unsigned int character;
91
92 assert(strlen(string) < sizeof(buf));
93
94 strncpy(buf, string, sizeof(buf));
95 charset_len = strlen(charset);
96
97 for (i = 0; i < operations; i++)
98 {
99 offset = prng_rand(prng) % strlen(buf);
100 op = prng_rand(prng) % 3;
101
102 switch (op)
103 {
104 case 0:
105 /* replace */
106 character = prng_rand(prng) % charset_len;
107 buf[offset] = charset[character];
108 break;
109 case 1:
110 /* remove */
111 memmove(buf + offset, buf + offset + 1, strlen(buf) - offset);
112 break;
113 case 2:
114 /* insert */
115 assert(strlen(buf) + 1 < sizeof(buf));
116
117 memmove(buf + offset + 1, buf + offset, strlen(buf) + 1 - offset);
118 character = prng_rand(prng) % charset_len;
119 buf[offset] = charset[character];
120 break;
121 }
122 }
123 return buf;
124}
125
Christian Frankefa713d92013-07-05 15:35:37 +0000126void
127prng_free(struct prng *prng)
128{
129 free(prng);
130}