]> git.proxmox.com Git - mirror_frr.git/blob - tests/helpers/c/prng.c
Merge pull request #12845 from sri-mohan1/sri-mohan-ldp
[mirror_frr.git] / tests / helpers / c / prng.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Very simple prng to allow for randomized tests with reproducable
4 * results.
5 *
6 * Copyright (C) 2012 by Open Source Routing.
7 * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
8 * Copyright (C) 2017 Christian Franke
9 *
10 * This file is part of Quagga
11 */
12
13 #include <zebra.h>
14
15 #include <assert.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "prng.h"
20
21 struct prng {
22 uint64_t state;
23 };
24
25 struct prng *prng_new(unsigned long long seed)
26 {
27 struct prng *rv = calloc(sizeof(*rv), 1);
28 assert(rv);
29
30 rv->state = seed;
31
32 return rv;
33 }
34
35 /*
36 * This implementation has originally been provided to musl libc by
37 * Szabolcs Nagy <nsz at port70 dot net> in 2013 under the terms of
38 * the MIT license.
39 * It is a simple LCG which D.E. Knuth attributes to C.E. Haynes in
40 * TAOCP Vol2 3.3.4
41 */
42 int prng_rand(struct prng *prng)
43 {
44 prng->state = 6364136223846793005ULL * prng->state + 1;
45 return prng->state >> 33;
46 }
47
48 const char *prng_fuzz(struct prng *prng, const char *string,
49 const char *charset, unsigned int operations)
50 {
51 static char buf[256];
52 unsigned int charset_len;
53 unsigned int i;
54 unsigned int offset;
55 unsigned int op;
56 unsigned int character;
57
58 assert(strlen(string) < sizeof(buf));
59
60 strncpy(buf, string, sizeof(buf));
61 charset_len = strlen(charset);
62
63 for (i = 0; i < operations; i++) {
64 offset = prng_rand(prng) % strlen(buf);
65 op = prng_rand(prng) % 3;
66
67 switch (op) {
68 case 0:
69 /* replace */
70 character = prng_rand(prng) % charset_len;
71 buf[offset] = charset[character];
72 break;
73 case 1:
74 /* remove */
75 memmove(buf + offset, buf + offset + 1,
76 strlen(buf) - offset);
77 break;
78 case 2:
79 /* insert */
80 assert(strlen(buf) + 1 < sizeof(buf));
81
82 memmove(buf + offset + 1, buf + offset,
83 strlen(buf) + 1 - offset);
84 character = prng_rand(prng) % charset_len;
85 buf[offset] = charset[character];
86 break;
87 }
88 }
89 return buf;
90 }
91
92 void prng_free(struct prng *prng)
93 {
94 free(prng);
95 }