Import ezmlm-idx 0.40
[ezmlm] / makehash.c
CommitLineData
f8beb284
MW
1/*Id:$*/
2/*Name:$*/
3
4#include "stralloc.h"
5#include "surf.h"
6#include "uint32.h"
7#include "makehash.h"
8
9typedef struct {
10 uint32 seed[32];
11 uint32 sum[8];
12 uint32 out[8];
13 uint32 in[12];
14 int todo;
15} surfpcs;
16
17#define SURFPCS_LEN 32
18
19static void surfpcs_init(s,k)
20surfpcs *s;
21uint32 k[32];
22{
23 int i;
24 for (i = 0;i < 32;++i) s->seed[i] = k[i];
25 for (i = 0;i < 8;++i) s->sum[i] = 0;
26 for (i = 0;i < 12;++i) s->in[i] = 0;
27 s->todo = 0;
28}
29
30static uint32 littleendian[8] = {
31 50462976, 117835012, 185207048, 252579084,
32 319951120, 387323156, 454695192, 522067228
33} ;
34#define end ((unsigned char *) littleendian)
35
36#define data ((unsigned char *) s->in)
37#define outdata ((unsigned char *) s->out)
38
39static void surfpcs_addlc(s,x,n)
40 /* modified from Dan's surfpcs_add by skipping ' ' & '\t' and */
41 /* case-independence */
42surfpcs *s;
43unsigned char *x;
44unsigned int n;
45{
46 register unsigned char ch;
47 int i;
48 while (n--) {
49 ch = *x++;
50 if (ch == ' ' || ch == '\t') continue;
51 if (ch >= 'A' && ch <= 'Z')
52 data[end[s->todo++]] = ch - 'A' + 'a';
53 else
54 data[end[s->todo++]] = ch;
55 if (s->todo == 32) {
56 s->todo = 0;
57 if (!++s->in[8])
58 if (!++s->in[9])
59 if (!++s->in[10])
60 ++s->in[11];
61 surf(s->out,s->in,s->seed);
62 for (i = 0;i < 8;++i)
63 s->sum[i] += s->out[i];
64 }
65 }
66}
67
68static void surfpcs_out(s,h)
69surfpcs *s;
70unsigned char h[32];
71{
72 int i;
73 surfpcs_addlc(s,".",1);
74 while (s->todo) surfpcs_addlc(s,"",1);
75 for (i = 0;i < 8;++i) s->in[i] = s->sum[i];
76 for (;i < 12;++i) s->in[i] = 0;
77 surf(s->out,s->in,s->seed);
78 for (i = 0;i < 32;++i) h[i] = outdata[end[i]];
79}
80
81void makehash(indata,inlen,hash)
82char *indata;
83unsigned int inlen;
84char *hash;
85 /* makes hash[COOKIE=20] from stralloc *indata, ignoring case and */
86 /* SPACE/TAB */
87{
88 unsigned char h[32];
89 surfpcs s;
90 uint32 seed[32];
91 int i;
92
93 for (i = 0;i < 32;++i) seed[i] = 0;
94 surfpcs_init(&s,seed);
95 surfpcs_addlc(&s,indata,inlen);
96 surfpcs_out(&s,h);
97 for (i = 0;i < 20;++i)
98 hash[i] = 'a' + (h[i] & 15);
99}
100
101static stralloc dummy = {0};
102
103void mkauthhash(s,len,h)
104char *s; unsigned int len; char *h;
105/* This is a string that should be the same for all messages from a given */
106/* author. Doesn't have to be the real rfc822 address. We look for a '@' */
107/* and grab everything up to the next '>', ' ', or ';'. We go back the same */
108/* way, then take everything up to the '@' or the first '-'. The latter */
109/* avoids problems with posters that band their addresses. */
110{
111 unsigned int i,j,k,l;
112 register char ch;
113
114 j = k = l = 0;
115 i = byte_rchr(s,len,'@');
116 if (i < len) { /* if not then i=sa->len, j=k=l=0 */
117 j = i;
118 while (++j < len) { /* if not found, then j=sa->len */
119 ch = s[j];
120 if (ch == '>' || ch == ' ' || ch == ';') break;
121 }
122 k = i;
123 while (k > 0) { /* k <= i */
124 ch = s[--k];
125 if (ch == '<' || ch == ' ' || ch == ';') break;
126 }
127 l = k; /* k <= l <= i; */
128 while (l < i && s[l] != '-') ++l;
129 if (!stralloc_copyb(&dummy,s + k, l - k)) die_nomem();
130 if (!stralloc_catb(&dummy,s + i, j - i)) die_nomem();
131 makehash(dummy.s,dummy.len,h);
132 } else /* use entire line if no '@' found */
133 makehash(s,len,h);
134}
135
136