示例#1
0
/*
 * test_fnv32 - test the FNV32 hash
 *
 * given:
 *	hash_type	type of FNV hash to test
 *	init_hval	initial hash value
 *	mask	  	lower bit mask
 *	v_flag	  	1 => print test failure info on stderr
 *	code	  0 ==> generate FNV test vectors
 *		  1 ==> validate against FNV test vectors
 *
 * returns:	0 ==> OK, else test vector failure number
 */
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;	/* FNV test vestor */
    Fnv32_t hval;		/* current hash value */
    int tstnum;			/* test vector that failed, starting at 1 */

    /*
     * print preamble if generating test vectors
     */
    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);	/* exit(12) */
	    /*NOTREACHED*/
    	}
    }

    /*
     * loop thru all test vectors
     */
    for (t = fnv_test_str, tstnum = 1; t->buf != NULL; ++t, ++tstnum) {

        /*
	 * compute the FNV hash
	 */
	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);	/* exit(13) */
	    /*NOTREACHED*/
	}

	/*
	 * print the vector
	 */
	switch (code) {
	case 0:		/* generate the test vector */
	    printf("    { &fnv_test_str[%d], (Fnv32_t) 0x%08lxUL },\n",
	    	    tstnum-1, hval & mask);
    	    break;
	case 1:		/* validate against test vector */
	    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);
    	}
    }

    /*
     * print completion if generating test vectors
     */
    if (code == 0) {
	printf("    { NULL, 0 }\n");
	printf("};\n");
    }

    /*
     * no failures, return code 0 ==> all OK
     */
    return 0;
}
示例#2
0
static unsigned hashmap_hash(void* buf, size_t len)
{
	return fnv_32a_buf(buf, len, FNV1_32A_INIT);
}
示例#3
0
/*
 * main - the main function
 *
 * See the above usage for details.
 */
int
main(int argc, char *argv[])
{
    char buf[BUF_SIZE+1];	/* read buffer */
    int readcnt;		/* number of characters written */
    Fnv32_t hval;		/* current hash value */
    int s_flag = 0;		/* 1 => -s was given, hash args as strings */
    int m_flag = 0;		/* 1 => print multiple hashes, one per arg */
    int v_flag = 0;		/* 1 => verbose hash print */
    int b_flag = WIDTH;		/* -b flag value */
    int t_flag = -1;		/* FNV test vector code (0=>print, 1=>test) */
    enum fnv_type hash_type = FNV_NONE;	/* type of FNV hash to perform */
    Fnv32_t bmask;		/* mask to apply to output */
    extern char *optarg;	/* option argument */
    extern int optind;		/* argv index of the next arg */
    int fd;			/* open file to process */
    char *p;
    int i;

    /*
     * parse args
     */
    program = argv[0];
    while ((i = getopt(argc, argv, "b:mst:v")) != -1) {
	switch (i) {
	case 'b':	/* bcnt bit mask count */
	    b_flag = atoi(optarg);
	    break;
	case 'm':	/* print multiple hashes, one per arg */
	    m_flag = 1;
	    break;
	case 's':	/* hash args as strings */
	    s_flag = 1;
	    break;
	case 't':	/* FNV test vector code */
	    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':	/* verbose hash print */
	    m_flag = 1;
	    v_flag = 1;
	    break;
	default:
	    fprintf(stderr, usage, program, FNV_VERSION);
	    exit(1);
	}
    }
    /* -t code incompatible with -b, -m and args */
    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);
	}
    }
    /* -s requires at least 1 arg */
    if (s_flag && optind >= argc) {
	fprintf(stderr, usage, program, FNV_VERSION);
	exit(5);
    }
    /* limit -b values */
    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);
    }

    /*
     * start with the initial basis depending on the hash type
     */
    p = strrchr(program, '/');
    if (p == NULL) {
	p = program;
    } else {
	++p;
    }
    if (strcmp(p, "fnv032") == 0) {
	/* using non-recommended FNV-0 and zero initial basis */
	hval = FNV0_32_INIT;
	hash_type = FNV0_32;
    } else if (strcmp(p, "fnv132") == 0) {
	/* using FNV-1 and non-zero initial basis */
	hval = FNV1_32_INIT;
	hash_type = FNV1_32;
    } else if (strcmp(p, "fnv1a32") == 0) {
	 /* start with the FNV-1a initial basis */
	hval = FNV1_32A_INIT;
	hash_type = FNV1a_32;
    } else {
	fprintf(stderr, "%s: unknown program name, unknown hash type\n",
		program);
	exit(7);
    }

    /*
     * FNV test vector processing, if needed
     */
    if (t_flag >= 0) {
	int code;		/* test vector that failed, starting at 1 */

	/*
	 * perform all tests
	 */
	code = test_fnv32(hash_type, hval, bmask, v_flag, t_flag);

	/*
	 * evaluate the tests
	 */
	if (code == 0) {
	    if (v_flag) {
	    	printf("passed\n");
	    }
	    exit(0);
	} else {
	    printf("failed vector (1 is 1st test): %d\n", code);
	    exit(8);
	}
    }

    /*
     * string hashing
     */
    if (s_flag) {

	/* hash any other strings */
	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);	/* exit(9) */
		/*NOTREACHED*/
	    }
	    if (m_flag) {
		print_fnv32(hval, bmask, v_flag, argv[i]);
	    }
	}


    /*
     * file hashing
     */
    } else {

	/*
	 * case: process only stdin
	 */
	if (optind >= argc) {

	    /* case: process only stdin */
	    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);
		default:
		    unknown_hash_type(program, hash_type, 10);	/* exit(10) */
		    /*NOTREACHED*/
		}
	    }
	    if (m_flag) {
		print_fnv32(hval, bmask, v_flag, "(stdin)");
	    }

	} else {

	    /*
	     * process any other files
	     */
	    for (i=optind; i < argc; ++i) {

		/* open the file */
		fd = open(argv[i], O_RDONLY);
		if (fd < 0) {
		    fprintf(stderr, "%s: unable to open file: %s\n",
			    program, argv[i]);
		    exit(4);
		}

		/*  hash the file */
		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);
		    default:
			unknown_hash_type(program, hash_type, 11);/* exit(11) */
			/*NOTREACHED*/
		    }
		}

		/* finish processing the file */
		if (m_flag) {
		    print_fnv32(hval, bmask, v_flag, argv[i]);
		}
		close(fd);
	    }
	}
    }

    /*
     * report hash and exit
     */
    if (!m_flag) {
	print_fnv32(hval, bmask, v_flag, "");
    }
    return 0;	/* exit(0); */
}