1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
/*
* LIB/HASH.C
*
* (c)Copyright 1997, Matthew Dillon, All Rights Reserved. Refer to
* the COPYRIGHT file in the base directory of this distribution
* for specific rights granted.
*
* CRC hash generator
*/
#include "defs.h"
Prototype hash_t hhash(const char *msgid);
Prototype void bhash(hash_t *h, const char *p, int len);
Prototype const char *GFName(const char *group, const char *prefix, int artBase);
#define P1 7834891
#define P2 6017489
#define HINIT1 0xFAC432B1
#define HINIT2 0x0CD5E44A
#define POLY1 0x00600340UL
#define POLY2 0x00F0D50BUL
#define OPOLY2 0x00F0D50AUL
hash_t CrcXor[3][256];
int DidCrcInit;
void
crcinit(int method)
{
int i;
for (i = 0; i < 256; ++i) {
int j;
int v = i;
hash_t hv = { 0, 0 };
for (j = 0; j < 8; ++j, (v <<= 1)) {
if (v & 0x80) {
hv.h1 ^= POLY1;
hv.h2 ^= (method == HASH_CRC) ? POLY2 : OPOLY2;
}
hv.h2 = (hv.h2 << 1);
if (hv.h1 & 0x80000000)
hv.h2 |= 1;
hv.h1 <<= 1;
}
CrcXor[method][i] = hv;
}
DidCrcInit = 1;
}
hash_t
hhash(const char *msgid)
{
hash_t t;
if (DiabloHashMethod == HASH_CRC || DiabloHashMethod == HASH_OCRC) {
/*
* HASH_CRC - CRC64
*/
if (DidCrcInit == 0) {
crcinit(HASH_CRC);
crcinit(HASH_OCRC);
}
t.h1 = HINIT1;
t.h2 = HINIT2;
while (*msgid) {
int i = (t.h1 >> 24) & 255;
t.h1 = (t.h1 << 8) ^ (int)((uint32)t.h2 >> 24) ^ CrcXor[DiabloHashMethod][i].h1;
t.h2 = (t.h2 << 8) ^ (uint8)*msgid ^ CrcXor[DiabloHashMethod][i].h2;
++msgid;
}
if (t.h1 & 0x80000000)
t.h1 = (t.h1 & 0x7FFFFFFF) | 1;
if (t.h2 & 0x80000000)
t.h2 = (t.h2 & 0x7FFFFFFF) | 1;
t.h1 |= 0x80000000; /* indicate CRC64 hash */
} else {
/*
* HASH_PRIME
*/
int h1 = 0x0034629D;
int h2 = 0x007395DD;
int hv = 0x1A3F5C4F;
while (*msgid) {
h1 = h1 * *(const unsigned char *)msgid % P1;
h2 = h2 * *(const unsigned char *)msgid % P2;
hv = (hv << 5) ^ *(const unsigned char *)msgid ^ (hv >> 23);
++msgid;
}
t.h1 = (h1 ^ (hv << 14)) & 0x7FFFFFFF; /* bit 31 reserved */
t.h2 = (h2 ^ (hv << 20)) & 0x7FFFFFFF; /* bit 31 reserved */
}
return(t);
}
/*
* Slightly different and faster hash algorithm to handle message bodies.
* This is simpler.
*/
void
bhash(hash_t *h, const char *p, int len)
{
while (len) {
h->h1 += *(unsigned char *)p; /* simple checksum */
h->h2 = (h->h2 << 5) ^ h->h1 ^ (h->h2 >> 27);
++p;
--len;
}
}
const char *
GFName(const char *group, const char *prefix, int artBase)
{
hash_t hv = hhash(group);
static char GFBuf[64];
snprintf(GFBuf, sizeof(GFBuf), "%02lx/%s.%d.%08lx.%08lx",
(long)(uint8)hv.h1,
prefix,
artBase,
(long)hv.h1,
(long)hv.h2
);
return(GFBuf);
}
|