]> git.proxmox.com Git - mirror_frr.git/blob - tests/helpers/c/prng.c
release: FRR 3.0-rc1
[mirror_frr.git] / tests / helpers / c / prng.c
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 unsigned long long state1;
36 unsigned long long state2;
37 };
38
39 static char prng_bit(struct prng *prng)
40 {
41 prng->state1 *= 2416;
42 prng->state1 += 374441;
43 prng->state1 %= 1771875;
44
45 if (prng->state1 % 2) {
46 prng->state2 *= 84589;
47 prng->state2 += 45989;
48 prng->state2 %= 217728;
49 }
50
51 return prng->state2 % 2;
52 }
53
54 struct prng *prng_new(unsigned long long seed)
55 {
56 struct prng *rv = calloc(sizeof(*rv), 1);
57 assert(rv);
58
59 rv->state1 = rv->state2 = seed;
60
61 return rv;
62 }
63
64 unsigned int prng_rand(struct prng *prng)
65 {
66 unsigned int i, rv = 0;
67
68 for (i = 0; i < 32; i++) {
69 rv |= prng_bit(prng);
70 rv <<= 1;
71 }
72 return rv;
73 }
74
75 const char *prng_fuzz(struct prng *prng, const char *string,
76 const char *charset, unsigned int operations)
77 {
78 static char buf[256];
79 unsigned int charset_len;
80 unsigned int i;
81 unsigned int offset;
82 unsigned int op;
83 unsigned int character;
84
85 assert(strlen(string) < sizeof(buf));
86
87 strncpy(buf, string, sizeof(buf));
88 charset_len = strlen(charset);
89
90 for (i = 0; i < operations; i++) {
91 offset = prng_rand(prng) % strlen(buf);
92 op = prng_rand(prng) % 3;
93
94 switch (op) {
95 case 0:
96 /* replace */
97 character = prng_rand(prng) % charset_len;
98 buf[offset] = charset[character];
99 break;
100 case 1:
101 /* remove */
102 memmove(buf + offset, buf + offset + 1,
103 strlen(buf) - offset);
104 break;
105 case 2:
106 /* insert */
107 assert(strlen(buf) + 1 < sizeof(buf));
108
109 memmove(buf + offset + 1, buf + offset,
110 strlen(buf) + 1 - offset);
111 character = prng_rand(prng) % charset_len;
112 buf[offset] = charset[character];
113 break;
114 }
115 }
116 return buf;
117 }
118
119 void prng_free(struct prng *prng)
120 {
121 free(prng);
122 }