123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <string.h>
- #include "longlong.h"
- #include "fnv.h"
- #define WIDTH 32
- #define BUF_SIZE (32*1024)
- static char *usage =
- "usage: %s [-b bcnt] [-m] [-s arg] [-t code] [-v] [arg ...]\n"
- "\n"
- "\t-b bcnt\tmask off all but the lower bcnt bits (default 32)\n"
- "\t-m\tmultiple hashes, one per line for each arg\n"
- "\t-s\thash arg as a string (ignoring terminating NUL bytes)\n"
- "\t-t code\t test hash code: (0 ==> generate test vectors\n"
- "\t\t\t\t 1 ==> validate against FNV test vectors)\n"
- "\t-v\tverbose mode, print arg after hash (implies -m)\n"
- "\targ\tstring (if -s was given) or filename (default stdin)\n"
- "\n"
- "\tNOTE: Programs that begin with fnv0 implement the FNV-0 hash.\n"
- "\t The FNV-0 hash is historic FNV algorithm that is now deprecated.\n"
- "\n"
- "\tSee http://www.isthe.com/chongo/tech/comp/fnv/index.html for more info.\n"
- "\n"
- "\t@(#) FNV Version: %s\n";
- static char *program;
- static int
- test_fnv32(enum fnv_type hash_type, Fnv32_t init_hval,
- Fnv32_t mask, int v_flag, int code)
- {
- struct test_vector *t;
- Fnv32_t hval;
- int tstnum;
-
- if (code == 0) {
- switch (hash_type) {
- case FNV0_32:
- printf("struct fnv0_32_test_vector fnv0_32_vector[] = {\n");
- break;
- case FNV1_32:
- printf("struct fnv1_32_test_vector fnv1_32_vector[] = {\n");
- break;
- case FNV1a_32:
- printf("struct fnv1a_32_test_vector fnv1a_32_vector[] = {\n");
- break;
- default:
- unknown_hash_type(program, hash_type, 12);
-
- }
- }
-
- for (t = fnv_test_str, tstnum = 1; t->buf != NULL; ++t, ++tstnum) {
-
- hval = init_hval;
- switch (hash_type) {
- case FNV0_32:
- case FNV1_32:
- hval = fnv_32_buf(t->buf, t->len, hval);
- break;
- case FNV1a_32:
- hval = fnv_32a_buf(t->buf, t->len, hval);
- break;
- default:
- unknown_hash_type(program, hash_type, 13);
-
- }
-
- switch (code) {
- case 0:
- printf(" { &fnv_test_str[%d], (Fnv32_t) 0x%08lxUL },\n",
- tstnum-1, hval & mask);
- break;
- case 1:
- switch (hash_type) {
- case FNV0_32:
- if ((hval&mask) != (fnv0_32_vector[tstnum-1].fnv0_32 & mask)) {
- if (v_flag) {
- fprintf(stderr, "%s: failed fnv0_32 test # %d\n",
- program, tstnum);
- fprintf(stderr, "%s: test # 1 is 1st test\n", program);
- fprintf(stderr,
- "%s: expected 0x%08lx != generated: 0x%08lx\n",
- program, (hval&mask),
- (fnv0_32_vector[tstnum-1].fnv0_32 & mask));
- }
- return tstnum;
- }
- break;
- case FNV1_32:
- if ((hval&mask) != (fnv1_32_vector[tstnum-1].fnv1_32 & mask)) {
- if (v_flag) {
- fprintf(stderr, "%s: failed fnv1_32 test # %d\n",
- program, tstnum);
- fprintf(stderr, "%s: test # 1 is 1st test\n", program);
- fprintf(stderr,
- "%s: expected 0x%08lx != generated: 0x%08lx\n",
- program, (hval&mask),
- (fnv1_32_vector[tstnum-1].fnv1_32 & mask));
- }
- return tstnum;
- }
- break;
- case FNV1a_32:
- if ((hval&mask) != (fnv1a_32_vector[tstnum-1].fnv1a_32 &mask)) {
- if (v_flag) {
- fprintf(stderr, "%s: failed fnv1a_32 test # %d\n",
- program, tstnum);
- fprintf(stderr, "%s: test # 1 is 1st test\n", program);
- fprintf(stderr,
- "%s: expected 0x%08lx != generated: 0x%08lx\n",
- program, (hval&mask),
- (fnv1a_32_vector[tstnum-1].fnv1a_32 & mask));
- }
- return tstnum;
- }
- break;
- }
- break;
- default:
- fprintf(stderr, "%s: -m %d not implemented yet\n", program, code);
- exit(14);
- }
- }
-
- if (code == 0) {
- printf(" { NULL, 0 }\n");
- printf("};\n");
- }
-
- return 0;
- }
- int
- main(int argc, char *argv[])
- {
- char buf[BUF_SIZE+1];
- int readcnt;
- Fnv32_t hval;
- int s_flag = 0;
- int m_flag = 0;
- int v_flag = 0;
- int b_flag = WIDTH;
- int t_flag = -1;
- enum fnv_type hash_type = FNV_NONE;
- Fnv32_t bmask;
- extern char *optarg;
- extern int optind;
- int fd;
- char *p;
- int i;
-
- program = argv[0];
- while ((i = getopt(argc, argv, "b:mst:v")) != -1) {
- switch (i) {
- case 'b':
- b_flag = atoi(optarg);
- break;
- case 'm':
- m_flag = 1;
- break;
- case 's':
- s_flag = 1;
- break;
- case 't':
- t_flag = atoi(optarg);
- if (t_flag < 0 || t_flag > 1) {
- fprintf(stderr, "%s: -t code must be 0 or 1\n", program);
- fprintf(stderr, usage, program, FNV_VERSION);
- exit(1);
- }
- m_flag = 1;
- break;
- case 'v':
- m_flag = 1;
- v_flag = 1;
- break;
- default:
- fprintf(stderr, usage, program, FNV_VERSION);
- exit(1);
- }
- }
-
- if (t_flag >= 0) {
- if (b_flag != WIDTH) {
- fprintf(stderr, "%s: -t code incompatible with -b\n", program);
- exit(2);
- }
- if (s_flag != 0) {
- fprintf(stderr, "%s: -t code incompatible with -s\n", program);
- exit(3);
- }
- if (optind < argc) {
- fprintf(stderr, "%s: -t code incompatible args\n", program);
- exit(4);
- }
- }
-
- if (s_flag && optind >= argc) {
- fprintf(stderr, usage, program, FNV_VERSION);
- exit(5);
- }
-
- if (b_flag < 0 || b_flag > WIDTH) {
- fprintf(stderr, "%s: -b bcnt: %d must be >= 0 and < %d\n",
- program, b_flag, WIDTH);
- exit(6);
- }
- if (b_flag == WIDTH) {
- bmask = (Fnv32_t)0xffffffff;
- } else {
- bmask = (Fnv32_t)((1 << b_flag) - 1);
- }
-
- p = strrchr(program, '/');
- if (p == NULL) {
- p = program;
- } else {
- ++p;
- }
- if (strcmp(p, "fnv032") == 0) {
-
- hval = FNV0_32_INIT;
- hash_type = FNV0_32;
- } else if (strcmp(p, "fnv132") == 0) {
-
- hval = FNV1_32_INIT;
- hash_type = FNV1_32;
- } else if (strcmp(p, "fnv1a32") == 0) {
-
- hval = FNV1_32A_INIT;
- hash_type = FNV1a_32;
- } else {
- fprintf(stderr, "%s: unknown program name, unknown hash type\n",
- program);
- exit(7);
- }
-
- if (t_flag >= 0) {
- int code;
-
- code = test_fnv32(hash_type, hval, bmask, v_flag, t_flag);
-
- if (code == 0) {
- if (v_flag) {
- printf("passed\n");
- }
- exit(0);
- } else {
- printf("failed vector (1 is 1st test): %d\n", code);
- exit(8);
- }
- }
-
- if (s_flag) {
-
- for (i=optind; i < argc; ++i) {
- switch (hash_type) {
- case FNV0_32:
- case FNV1_32:
- hval = fnv_32_str(argv[i], hval);
- break;
- case FNV1a_32:
- hval = fnv_32a_str(argv[i], hval);
- break;
- default:
- unknown_hash_type(program, hash_type, 9);
-
- }
- if (m_flag) {
- print_fnv32(hval, bmask, v_flag, argv[i]);
- }
- }
-
- } else {
-
- if (optind >= argc) {
-
- while ((readcnt = read(0, buf, BUF_SIZE)) > 0) {
- switch (hash_type) {
- case FNV0_32:
- case FNV1_32:
- hval = fnv_32_buf(buf, readcnt, hval);
- break;
- case FNV1a_32:
- hval = fnv_32a_buf(buf, readcnt, hval);
- break;
- default:
- unknown_hash_type(program, hash_type, 10);
-
- }
- }
- if (m_flag) {
- print_fnv32(hval, bmask, v_flag, "(stdin)");
- }
- } else {
-
- for (i=optind; i < argc; ++i) {
-
- fd = open(argv[i], O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "%s: unable to open file: %s\n",
- program, argv[i]);
- exit(4);
- }
-
- while ((readcnt = read(fd, buf, BUF_SIZE)) > 0) {
- switch (hash_type) {
- case FNV0_32:
- case FNV1_32:
- hval = fnv_32_buf(buf, readcnt, hval);
- break;
- case FNV1a_32:
- hval = fnv_32a_buf(buf, readcnt, hval);
- break;
- default:
- unknown_hash_type(program, hash_type, 11);
-
- }
- }
-
- if (m_flag) {
- print_fnv32(hval, bmask, v_flag, argv[i]);
- }
- close(fd);
- }
- }
- }
-
- if (!m_flag) {
- print_fnv32(hval, bmask, v_flag, "");
- }
- return 0;
- }
|