Explorar el Código

Initial commit

Yann Weber hace 2 años
commit
d546c18096
Se han modificado 2 ficheros con 227 adiciones y 0 borrados
  1. 23
    0
      Makefile
  2. 204
    0
      sadrand.c

+ 23
- 0
Makefile Ver fichero

@@ -0,0 +1,23 @@
1
+CC=gcc
2
+CFLAGS=-Wall
3
+LDFLAGS=-lm
4
+
5
+all: sadrand
6
+
7
+sadrand: sadrand.o
8
+	$(CC) -o $@ $< $(LDFLAGS)
9
+
10
+sadrand.o: sadrand.c
11
+	$(CC) $(CFLAGS) -c -o $@ $<
12
+
13
+sadrand-dbg: sadrand-dbg.o
14
+	$(CC) -g -o $@ $< $(LDFLAGS)
15
+
16
+sadrand-dbg.o: sadrand.c
17
+	$(CC) -g $(CFLAGS) -c -o $@ $<
18
+
19
+
20
+.PHONY: clean
21
+
22
+clean:
23
+	-rm *.o

+ 204
- 0
sadrand.c Ver fichero

@@ -0,0 +1,204 @@
1
+#include <errno.h>
2
+#include <fcntl.h>
3
+#include <getopt.h>
4
+#include <math.h>
5
+#include <stdio.h>
6
+#include <stdlib.h>
7
+#include <string.h>
8
+#include <sys/random.h>
9
+#include <sys/stat.h>
10
+#include <sys/types.h>
11
+#include <unistd.h>
12
+
13
+#define NTEST 3
14
+
15
+struct rand_ctx
16
+{
17
+	unsigned char buf[4096];
18
+	int cur_read;
19
+};
20
+
21
+void usage(const char name[])
22
+{
23
+	dprintf(2, "Usage %s [resolution [iterations]]\n", name);
24
+}
25
+
26
+void rand_ctx_init(struct rand_ctx *ctx)
27
+{
28
+	ctx->cur_read = -1;
29
+}
30
+
31
+int randbits(char count, unsigned long *bits, struct rand_ctx *ctx)
32
+{
33
+	int ret;
34
+
35
+	*bits = 0;
36
+
37
+	if(count < 0 || count > 8*sizeof(unsigned long))
38
+	{
39
+		return -1;
40
+	}
41
+
42
+	if(sizeof(ctx->buf) - ctx->cur_read < (count/8)+1)
43
+	{
44
+		ctx->cur_read = -1;
45
+	}
46
+	if(ctx->cur_read < 0)
47
+	{
48
+		while(1)
49
+		{
50
+			ret = getrandom(ctx->buf, sizeof(ctx->buf), 0);
51
+			if(ret < 0) {
52
+				if(errno == EINTR) { continue; }
53
+				perror("Unable to get random bytes");
54
+				return -2;
55
+			}
56
+			break;
57
+		}
58
+		ctx->cur_read = 0;
59
+	}
60
+
61
+	do {
62
+		if(count < 8)
63
+		{
64
+			*bits <<= count;
65
+			*bits |= ctx->buf[ctx->cur_read] & ((1<<count)-1);
66
+			count = 0;
67
+		}
68
+		else
69
+		{
70
+			*bits <<= 8;
71
+			*bits |= ctx->buf[ctx->cur_read];
72
+			count -= 8;
73
+		}
74
+		ctx->cur_read++;
75
+	}while(count);
76
+
77
+	return 0;
78
+}
79
+
80
+int std_rand(unsigned long iterations, unsigned char resolution, unsigned int *result)
81
+{	
82
+	unsigned long bits;
83
+	struct rand_ctx ctx;
84
+	char nbits;
85
+
86
+	nbits = (char)ceilf(log2f(resolution));
87
+
88
+	rand_ctx_init(&ctx);
89
+
90
+	for(unsigned long i = 0; i<iterations; i++)
91
+	{
92
+		do
93
+		{
94
+			if(randbits(nbits, &bits, &ctx) < 0) {
95
+				perror("Unable to get random bits");
96
+				return -1;
97
+			}
98
+		}while(bits > resolution-1);
99
+		result[bits]++;
100
+	}
101
+
102
+	return 0;
103
+}
104
+
105
+int mod_rand(unsigned long iterations, unsigned char resolution, unsigned int *result)
106
+{
107
+	unsigned long bits;
108
+
109
+	struct rand_ctx ctx;
110
+
111
+	rand_ctx_init(&ctx);
112
+
113
+	for(unsigned long i = 0; i<iterations; i++)
114
+	{
115
+		if(randbits(8, &bits, &ctx) < 0) {
116
+			perror("Unable to get random bits");
117
+			return -1;
118
+		}
119
+		result[bits%resolution]++;
120
+	}
121
+	return 0;
122
+}
123
+
124
+int prop_rand(unsigned long iterations, unsigned char resolution, unsigned int *result)
125
+{
126
+	unsigned long bits;
127
+
128
+	struct rand_ctx ctx;
129
+
130
+	rand_ctx_init(&ctx);
131
+
132
+	for(unsigned long i = 0; i<iterations; i++)
133
+	{
134
+		if(randbits(8, &bits, &ctx) < 0)
135
+		{
136
+			perror("Unable to get random bits");
137
+			return -1;
138
+		}
139
+		result[(bits * resolution) / 256]++;
140
+	}
141
+	return 0;
142
+}
143
+
144
+void print_result(unsigned char resolution, unsigned int *result)
145
+{
146
+	printf("[");
147
+	for(int i=0; i<resolution; i++)
148
+	{
149
+		printf("%d%s", result[i], i<resolution-1?", ":"");
150
+	}
151
+	printf("]\n");
152
+}
153
+
154
+void print_results(unsigned char resolution, unsigned int *results[NTEST])
155
+{
156
+	for(int i=0; i<resolution; i++)
157
+	{
158
+		printf("%d %d ", resolution, i);
159
+		for(int j=0; j<NTEST; j++)
160
+		{
161
+			printf("%d ", results[j][i]);
162
+		}
163
+		printf("\n");
164
+	}
165
+}
166
+
167
+int main(int argc, char *argv[]) {
168
+	
169
+	char *foo;
170
+	unsigned char resolution = argc < 2 ? 100 : atoi(argv[1]);
171
+	unsigned long iterations = argc < 3 ? 0x100000 : strtoll(argv[2], NULL, 0);
172
+
173
+	if(!resolution || !iterations)
174
+	{
175
+		usage(argv[0]);
176
+		exit(0);
177
+	}
178
+
179
+	unsigned int *results[NTEST];
180
+
181
+	for(int i=0; i<NTEST; i++)
182
+	{
183
+		if( !(results[i] = malloc(sizeof(unsigned int) * resolution)) )
184
+		{
185
+			perror("Unable to allocate results array");
186
+			return 1;
187
+		}
188
+		bzero(results[i], sizeof(unsigned int)*resolution);
189
+	}
190
+
191
+	std_rand(iterations, resolution, results[0]);
192
+	mod_rand(iterations, resolution, results[1]);
193
+	prop_rand(iterations, resolution, results[2]);
194
+
195
+	print_results(resolution, results);
196
+
197
+	for(int i=0; i<NTEST; i++)
198
+	{
199
+		free(results[i]);
200
+	}
201
+
202
+	return 0;
203
+}
204
+

Loading…
Cancelar
Guardar