/* Copyright (C) Slava Astashonok This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License. $Id: hash.c,v 1.3.2.2.2.1 2005/01/29 19:30:41 sla Exp $ */ #include #include #include #include #include #include #include #ifdef HASH_TYPE_CRC static uint16_t crc16_poly; static uint8_t shuffle_table[256]; static uint16_t crc16_table[256]; uint16_t crc16(uint16_t crc, uint8_t val) { int i; crc ^= val << 8; for (i = 8; i--; ) crc = crc & 0x8000 ? (crc << 1) ^ crc16_poly : crc << 1; return crc; } #endif hash_t hash(void *p, int size) { /* ?FIXME? Check for valid size (> 0) */ hash_t hash = 0; #if defined HASH_TYPE_XOR && HASH_BITS == 16 if (size & 1) hash = *((uint8_t *) p++); size >>= 1; #endif for (;size--;) { #ifdef HASH_TYPE_XOR hash ^= *((hash_t *) p++); # if HASH_BITS == 16 p++; # endif #endif #ifdef HASH_TYPE_CRC hash = crc16_table[shuffle_table[*((uint8_t *) p++)] \ ^ (hash >> 8)] ^ (hash << 8); #endif } return hash; } void hash_init() { #ifdef HASH_TYPE_CRC int rnd, i, j, m; FILE *rnddev; if ((rnddev = fopen(RNDDEV, "r"))) { fcntl(fileno(rnddev), F_SETFL, \ fcntl(fileno(rnddev), F_GETFL) | O_NONBLOCK); fread(&rnd, sizeof(rnd), 1, rnddev); fclose(rnddev); } srand(time(NULL) ^ getpid() ^ rnd); crc16_poly = rand() | 1; for (i = 0; i < 256; i++) { crc16_table[i] = crc16(0, i); shuffle_table[i] = i; } for (i = 0; i < 256; i++) { j = (int) (256.0 * rand() / (RAND_MAX + 1.0)); m = shuffle_table[i]; shuffle_table[i] = shuffle_table[j]; shuffle_table[j] = m; } #endif }