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
|
#include "surf.h"
#include "uint32.h"
typedef struct {
uint32 seed[32];
uint32 sum[8];
uint32 out[8];
uint32 in[12];
int todo;
} surfpcs;
#define SURFPCS_LEN 32
static void surfpcs_init(s,k)
surfpcs *s;
uint32 k[32];
{
int i;
for (i = 0;i < 32;++i) s->seed[i] = k[i];
for (i = 0;i < 8;++i) s->sum[i] = 0;
for (i = 0;i < 12;++i) s->in[i] = 0;
s->todo = 0;
}
static uint32 littleendian[8] = {
50462976, 117835012, 185207048, 252579084,
319951120, 387323156, 454695192, 522067228
} ;
#define end ((unsigned char *) littleendian)
#define data ((unsigned char *) s->in)
#define outdata ((unsigned char *) s->out)
static void surfpcs_addlc(s,x,n)
/* modified from Dan's surfpcs_add by skipping ' ' & '\t' and */
/* case-independence */
surfpcs *s;
unsigned char *x;
unsigned int n;
{
register unsigned char ch;
int i;
while (n--) {
ch = *x++;
if (ch == ' ' || ch == '\t') continue;
if (ch >= 'A' && ch <= 'Z')
data[end[s->todo++]] = ch - 'A' + 'a';
else
data[end[s->todo++]] = ch;
if (s->todo == 32) {
s->todo = 0;
if (!++s->in[8])
if (!++s->in[9])
if (!++s->in[10])
++s->in[11];
surf(s->out,s->in,s->seed);
for (i = 0;i < 8;++i)
s->sum[i] += s->out[i];
}
}
}
static void surfpcs_out(s,h)
surfpcs *s;
unsigned char h[32];
{
int i;
surfpcs_addlc(s,".",1);
while (s->todo) surfpcs_addlc(s,"",1);
for (i = 0;i < 8;++i) s->in[i] = s->sum[i];
for (;i < 12;++i) s->in[i] = 0;
surf(s->out,s->in,s->seed);
for (i = 0;i < 32;++i) h[i] = outdata[end[i]];
}
void makehash(indata,inlen,hash)
char *indata;
unsigned int inlen;
char *hash;
/* makes hash[COOKIE=20] from stralloc *indata, ignoring case and */
/* SPACE/TAB */
{
unsigned char h[32];
surfpcs s;
uint32 seed[32];
int i;
for (i = 0;i < 32;++i) seed[i] = 0;
surfpcs_init(&s,seed);
surfpcs_addlc(&s,indata,inlen);
surfpcs_out(&s,h);
for (i = 0;i < 20;++i)
hash[i] = 'a' + (h[i] & 15);
}
|