ext/ezmlm/hash/hash.c
changeset 23 eedb2586dea4
parent 17 23c7f5c8ee39
equal deleted inserted replaced
22:d1b9dd767e3a 23:eedb2586dea4
    11  * The following is copied verbatim from the ezmlm-idx source, version
    11  * The following is copied verbatim from the ezmlm-idx source, version
    12  * 7.2.2.  See: subhash.c, surf.c, and surfpcs.c.
    12  * 7.2.2.  See: subhash.c, surf.c, and surfpcs.c.
    13  *
    13  *
    14 */
    14 */
    15 
    15 
       
    16 static
    16 void surf(unsigned int out[8],const unsigned int in[12],const unsigned int seed[32])
    17 void surf(unsigned int out[8],const unsigned int in[12],const unsigned int seed[32])
    17 {
    18 {
    18   unsigned int t[12]; unsigned int x; unsigned int sum = 0;
    19   unsigned int t[12]; unsigned int x; unsigned int sum = 0;
    19   int r; int i; int loop;
    20   int r; int i; int loop;
    20 
    21 
    30     }
    31     }
    31     for (i = 0;i < 8;++i) out[i] ^= t[i + 4];
    32     for (i = 0;i < 8;++i) out[i] ^= t[i + 4];
    32   }
    33   }
    33 }
    34 }
    34 
    35 
       
    36 static
    35 void surfpcs_init(surfpcs *s,const unsigned int k[32])
    37 void surfpcs_init(surfpcs *s,const unsigned int k[32])
    36 {
    38 {
    37   int i;
    39   int i;
    38   for (i = 0;i < 32;++i) s->seed[i] = k[i];
    40   for (i = 0;i < 32;++i) s->seed[i] = k[i];
    39   for (i = 0;i < 8;++i) s->sum[i] = 0;
    41   for (i = 0;i < 8;++i) s->sum[i] = 0;
    40   for (i = 0;i < 12;++i) s->in[i] = 0;
    42   for (i = 0;i < 12;++i) s->in[i] = 0;
    41   s->todo = 0;
    43   s->todo = 0;
    42 }
    44 }
    43 
    45 
       
    46 static
    44 void surfpcs_add(surfpcs *s,const char *x,unsigned int n)
    47 void surfpcs_add(surfpcs *s,const char *x,unsigned int n)
    45 {
    48 {
    46   int i;
    49   int i;
    47   while (n--) {
    50   while (n--) {
    48     data[end[s->todo++]] = *x++;
    51     data[end[s->todo++]] = *x++;
    57 	s->sum[i] += s->out[i];
    60 	s->sum[i] += s->out[i];
    58     }
    61     }
    59   }
    62   }
    60 }
    63 }
    61 
    64 
       
    65 static
    62 void surfpcs_addlc(surfpcs *s,const char *x,unsigned int n)
    66 void surfpcs_addlc(surfpcs *s,const char *x,unsigned int n)
    63 /* modified from surfpcs_add by case-independence and skipping ' ' & '\t' */
    67 /* modified from surfpcs_add by case-independence and skipping ' ' & '\t' */
    64 {
    68 {
    65   unsigned char ch;
    69   unsigned char ch;
    66   int i;
    70   int i;
    82 	  s->sum[i] += s->out[i];
    86 	  s->sum[i] += s->out[i];
    83     }
    87     }
    84   }
    88   }
    85 }
    89 }
    86 
    90 
       
    91 static
    87 void surfpcs_out(surfpcs *s,unsigned char h[32])
    92 void surfpcs_out(surfpcs *s,unsigned char h[32])
    88 {
    93 {
    89   int i;
    94   int i;
    90   surfpcs_add(s,".",1);
    95   surfpcs_add(s,".",1);
    91   while (s->todo) surfpcs_add(s,"",1);
    96   while (s->todo) surfpcs_add(s,"",1);
    93   for (;i < 12;++i) s->in[i] = 0;
    98   for (;i < 12;++i) s->in[i] = 0;
    94   surf(s->out,s->in,s->seed);
    99   surf(s->out,s->in,s->seed);
    95   for (i = 0;i < 32;++i) h[i] = outdata[end[i]];
   100   for (i = 0;i < 32;++i) h[i] = outdata[end[i]];
    96 }
   101 }
    97 
   102 
       
   103 static
    98 void makehash(const char *indata,unsigned int inlen,char *hash)
   104 void makehash(const char *indata,unsigned int inlen,char *hash)
    99 	/* makes hash[COOKIE=20] from stralloc *indata, ignoring case and */
   105 	/* makes hash[COOKIE=20] from stralloc *indata, ignoring case and */
   100 	/* SPACE/TAB */
   106 	/* SPACE/TAB */
   101 {
   107 {
   102   unsigned char h[32];
   108   unsigned char h[32];
   110   surfpcs_out(&s,h);
   116   surfpcs_out(&s,h);
   111   for (i = 0;i < 20;++i)
   117   for (i = 0;i < 20;++i)
   112     hash[i] = 'a' + (h[i] & 15);
   118     hash[i] = 'a' + (h[i] & 15);
   113 }
   119 }
   114 
   120 
       
   121 static
   115 unsigned int subhashb(const char *s,long len)
   122 unsigned int subhashb(const char *s,long len)
   116 {
   123 {
   117   unsigned long h;
   124   unsigned long h;
   118   h = 5381;
   125   h = 5381;
   119   while (len-- > 0)
   126   while (len-- > 0)
   120     h = (h + (h << 5)) ^ (unsigned int)*s++;
   127     h = (h + (h << 5)) ^ (unsigned int)*s++;
   121   return h % 53;
   128   return h % 53;
   122 }
   129 }
   123 
   130 
       
   131 static
   124 unsigned int subhashs(const char *s)
   132 unsigned int subhashs(const char *s)
   125 {
   133 {
   126   return subhashb(s,strlen(s));
   134   return subhashb(s,strlen(s));
   127 }
   135 }
   128 
   136 
   130 
   138 
   131 
   139 
   132 
   140 
   133 
   141 
   134 /*
   142 /*
   135  * call­seq:
   143  * call-seq:
   136  *   Ezmlm::Hash.address( email ) -> String
   144  *   Ezmlm::Hash.address( email ) -> String
   137  *
   145  *
   138  * Call the Surf hashing function on an +email+ address, returning
   146  * Call the Surf hashing function on an +email+ address, returning
   139  * the hashed string.  This is specific to how ezmlm is seeding
   147  * the hashed string.  This is specific to how ezmlm is seeding
   140  * the hash, and parsing email addresses from messages (prefixed with
   148  * the hash, and parsing email addresses from messages (prefixed with
   141  * the '<' character.)
   149  * the '<' character.)
   142  *
   150  *
   143  */
   151  */
   144 VALUE
   152 static VALUE
   145 address( VALUE klass, VALUE email ) {
   153 address( VALUE klass, VALUE email ) {
   146 	char hash[20];
   154 	char hash[20];
   147 	char *input;
   155 	char *input;
   148 
   156 
   149 	Check_Type( email, T_STRING );
   157 	Check_Type( email, T_STRING );
   156 	return rb_str_new( hash, 20 );
   164 	return rb_str_new( hash, 20 );
   157 }
   165 }
   158 
   166 
   159 
   167 
   160 /*
   168 /*
   161  * call­seq:
   169  * call-seq:
   162  *   Ezmlm::Hash.subscriber( address ) -> String
   170  *   Ezmlm::Hash.subscriber( address ) -> String
   163  *
   171  *
   164  * Call the subscriber hashing function on an email +address+, returning
   172  * Call the subscriber hashing function on an email +address+, returning
   165  * the index character referring to the file containing subscriber presence.
   173  * the index character referring to the file containing subscriber presence.
   166  *
   174  *
   167  */
   175  */
   168 VALUE
   176 static VALUE
   169 subscriber( VALUE klass, VALUE email ) {
   177 subscriber( VALUE klass, VALUE email ) {
   170 	unsigned int prefix;
   178 	unsigned int prefix;
   171 
   179 
   172 	Check_Type( email, T_STRING );
   180 	Check_Type( email, T_STRING );
   173 
   181