]>
Commit | Line | Data |
---|---|---|
fa713d9e CF |
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 | ||
7a2fbbf0 DL |
26 | #include <zebra.h> |
27 | ||
fa713d9e CF |
28 | #include <assert.h> |
29 | #include <stdlib.h> | |
8f399b0e | 30 | #include <string.h> |
fa713d9e CF |
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 | ||
8f399b0e CF |
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 | ||
fa713d9e CF |
128 | void |
129 | prng_free(struct prng *prng) | |
130 | { | |
131 | free(prng); | |
132 | } |