10 #include <sys/types.h>
14 #include "mod_cuckoo.h"
17 #define LOTTERY_MAX 6 /* bytes */
19 static struct module
*hash_module
;
21 static sig_atomic_t show_status
, reload_table
;
22 static unsigned long nr_runs
, nr_found
, ulong_max
;
24 static void sig_handler(int signum
)
36 /* fatal(): print error message and exit */
37 static void fatal(const char *err
, ...)
41 fputs("ERROR: ", stderr
);
43 va_start(params
, err
);
44 vfprintf(stderr
, err
, params
);
52 /* FIXME: duplicated from load_file() */
53 static int self_test(const char *path
)
59 file
= fopen(path
, "r");
64 memset(line
, 0, sizeof(line
));
66 while (fgets(line
, sizeof(line
), file
) != NULL
) {
70 if (!strchr(line
, '\n')) {
73 while ((c
= getc(file
)) != '\n')
76 memset(line
, 0, sizeof(line
));
80 p
= strchr(line
, '\n');
84 found
= hash_module
->mod_lookup(line
, NULL
);
86 printf(" Could not found: %s\n", line
);
91 memset(line
, 0, sizeof(line
));
96 found
= hash_module
->mod_lookup("aaaaaaaaaaaaaaaaa", NULL
);
98 fprintf(stderr
, "found unknow string\n");
105 /* load the data from the file into the hash table */
106 static int load_file(const char *path
)
111 file
= fopen(path
, "r");
115 memset(line
, 0, sizeof(line
));
117 while (fgets(line
, sizeof(line
), file
) != NULL
) {
121 if (line
[0] == '#') {
122 if (!strchr(line
, '\n')) {
125 while ((c
= getc(file
)) != '\n')
128 memset(line
, 0, sizeof(line
));
132 p
= strchr(line
, '\n');
142 err
= hash_module
->mod_insert(p
);
149 /* else key already exists */
152 memset(line
, 0, sizeof(line
));
159 static int set_seed(void)
165 fd
= open("/dev/random", O_RDONLY
);
169 bytes
= read(fd
, &seed
, sizeof(seed
));
170 if (bytes
!= sizeof(seed
)) {
177 printf("\n-> Seed: %#X\n", seed
);
184 static void lottery(char *result
, size_t size
)
187 int numbers
[LOTTERY_MAX
];
189 memset(result
, 0, size
);
190 memset(numbers
, -1, sizeof(numbers
));
192 for (i
= 0; i
< LOTTERY_MAX
; i
++) {
196 num
= 1 + (int) (60.0 * (rand() / (RAND_MAX
+ 6.0)));
198 for (j
= 0; j
< i
; j
++)
199 if (numbers
[j
] == num
) {
211 snprintf(result
, size
, "%02d %02d %02d %02d %02d %02d",
212 numbers
[0], numbers
[1], numbers
[2],
213 numbers
[3], numbers
[4], numbers
[5]);
216 static void show_pid(void)
218 printf("-> PID: %d\n\n", getpid());
221 /* usage(): print usage info */
222 static void usage(void)
225 "usage: mega-sena [options] < -c | -l > < file >\n\n"
228 " -c use cuckoo hashing\n"
229 " -l use linear probing (open addressing)\n"
230 " -t run self test for selected hashing algorithm\n"
235 int main(int argc
, char *argv
[])
238 int opt
, run_stest
, err
;
239 char result
[LINE_LEN
], *path
;
244 while ((opt
= getopt(argc
, argv
, "htcl")) != -1 ) {
253 hash_module
= &lp_module
;
256 hash_module
= &cuckoo_module
;
265 fatal("you have to specify a filename");
268 fatal("you have to select a hash algorithm");
273 err
= hash_module
->mod_init();
275 perror("mod_init()");
279 err
= load_file(path
);
281 perror("load_file()");
286 hash_module
->mod_stats();
289 err
= self_test(path
);
290 printf("Performing self-test: ");
291 err
? printf("FAILED!\n") : printf("PASSED!\n");
298 perror("set_seed()");
304 signal(SIGUSR1
, sig_handler
);
305 signal(SIGHUP
, sig_handler
);
311 * The following checks will probably make the program
312 * run slower, but I've implemented them because they're
313 * cool features (specially the reload table one).
317 printf("-> Ran %lu (* %lu) times with %lu matches\n",
318 nr_runs
, ulong_max
, nr_found
);
324 * XXX: Reading all the file again isn't a smart
325 * way to do this, we could start reading from
326 * the last line read.
328 err
= load_file(path
);
330 perror("load_file()");
331 fprintf(stderr
, "Aborting...\n");
335 hash_module
->mod_stats();
339 lottery(result
, sizeof(result
));
341 found
= hash_module
->mod_lookup(result
, &hash
);
343 printf("-> HIT in run %lu: [%d] %s\n",
344 nr_runs
, hash
, result
);
348 if (++nr_runs
== ULONG_MAX
) {
349 if (++ulong_max
== ULONG_MAX
) {
350 printf("-> ulong_max blew up [%lu]\n",
359 hash_module
->mod_destroy();