⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lookup3.c

📁 一些经典的HASH函数及测试数据
💻 C
📖 第 1 页 / 共 3 页
字号:
    const uint8_t  *k8;    /*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */    while (length > 12)    {      a += k[0];      b += k[1];      c += k[2];      mix(a,b,c);      length -= 12;      k += 3;    }    /*----------------------------- handle the last (probably partial) block */    /*      * "k[2]<<8" actually reads beyond the end of the string, but     * then shifts out the part it's not allowed to read.  Because the     * string is aligned, the illegal read is in the same word as the     * rest of the string.  Every machine with memory protection I've seen     * does it on word boundaries, so is OK with this.  But VALGRIND will     * still catch it and complain.  The masking trick does make the hash     * noticably faster for short strings (like English words).     */#ifndef VALGRIND    switch(length)    {    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;    case 11: c+=k[2]&0xffffff00; b+=k[1]; a+=k[0]; break;    case 10: c+=k[2]&0xffff0000; b+=k[1]; a+=k[0]; break;    case 9 : c+=k[2]&0xff000000; b+=k[1]; a+=k[0]; break;    case 8 : b+=k[1]; a+=k[0]; break;    case 7 : b+=k[1]&0xffffff00; a+=k[0]; break;    case 6 : b+=k[1]&0xffff0000; a+=k[0]; break;    case 5 : b+=k[1]&0xff000000; a+=k[0]; break;    case 4 : a+=k[0]; break;    case 3 : a+=k[0]&0xffffff00; break;    case 2 : a+=k[0]&0xffff0000; break;    case 1 : a+=k[0]&0xff000000; break;    case 0 : return c;              /* zero length strings require no mixing */    }#else  /* make valgrind happy */    k8 = (const uint8_t *)k;    switch(length)                   /* all the case statements fall through */    {    case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;    case 11: c+=((uint32_t)k8[10])<<8;  /* fall through */    case 10: c+=((uint32_t)k8[9])<<16;  /* fall through */    case 9 : c+=((uint32_t)k8[8])<<24;  /* fall through */    case 8 : b+=k[1]; a+=k[0]; break;    case 7 : b+=((uint32_t)k8[6])<<8;   /* fall through */    case 6 : b+=((uint32_t)k8[5])<<16;  /* fall through */    case 5 : b+=((uint32_t)k8[4])<<24;  /* fall through */    case 4 : a+=k[0]; break;    case 3 : a+=((uint32_t)k8[2])<<8;   /* fall through */    case 2 : a+=((uint32_t)k8[1])<<16;  /* fall through */    case 1 : a+=((uint32_t)k8[0])<<24; break;    case 0 : return c;    }#endif /* !VALGRIND */  } else {                        /* need to read the key one byte at a time */    const uint8_t *k = (const uint8_t *)key;    /*--------------- all but the last block: affect some 32 bits of (a,b,c) */    while (length > 12)    {      a += ((uint32_t)k[0])<<24;      a += ((uint32_t)k[1])<<16;      a += ((uint32_t)k[2])<<8;      a += ((uint32_t)k[3]);      b += ((uint32_t)k[4])<<24;      b += ((uint32_t)k[5])<<16;      b += ((uint32_t)k[6])<<8;      b += ((uint32_t)k[7]);      c += ((uint32_t)k[8])<<24;      c += ((uint32_t)k[9])<<16;      c += ((uint32_t)k[10])<<8;      c += ((uint32_t)k[11]);      mix(a,b,c);      length -= 12;      k += 12;    }    /*-------------------------------- last block: affect all 32 bits of (c) */    switch(length)                   /* all the case statements fall through */    {    case 12: c+=k[11];    case 11: c+=((uint32_t)k[10])<<8;    case 10: c+=((uint32_t)k[9])<<16;    case 9 : c+=((uint32_t)k[8])<<24;    case 8 : b+=k[7];    case 7 : b+=((uint32_t)k[6])<<8;    case 6 : b+=((uint32_t)k[5])<<16;    case 5 : b+=((uint32_t)k[4])<<24;    case 4 : a+=k[3];    case 3 : a+=((uint32_t)k[2])<<8;    case 2 : a+=((uint32_t)k[1])<<16;    case 1 : a+=((uint32_t)k[0])<<24;             break;    case 0 : return c;    }  }  final(a,b,c);  return c;}#ifdef SELF_TEST/* used for timings */void driver1(){  uint8_t buf[256];  uint32_t i;  uint32_t h=0;  time_t a,z;  time(&a);  for (i=0; i<256; ++i) buf[i] = 'x';  for (i=0; i<1; ++i)   {    h = hashlittle(&buf[0],1,h);  }  time(&z);  if (z-a > 0) printf("time %d %.8x\n", z-a, h);}/* check that every input bit changes every output bit half the time */#define HASHSTATE 1#define HASHLEN   1#define MAXPAIR 60#define MAXLEN  70void driver2(){  uint8_t qa[MAXLEN+1], qb[MAXLEN+2], *a = &qa[0], *b = &qb[1];  uint32_t c[HASHSTATE], d[HASHSTATE], i=0, j=0, k, l, m=0, z;  uint32_t e[HASHSTATE],f[HASHSTATE],g[HASHSTATE],h[HASHSTATE];  uint32_t x[HASHSTATE],y[HASHSTATE];  uint32_t hlen;  printf("No more than %d trials should ever be needed \n",MAXPAIR/2);  for (hlen=0; hlen < MAXLEN; ++hlen)  {    z=0;    for (i=0; i<hlen; ++i)  /*----------------------- for each input byte, */    {      for (j=0; j<8; ++j)   /*------------------------ for each input bit, */      {	for (m=1; m<8; ++m) /*------------ for serveral possible initvals, */	{	  for (l=0; l<HASHSTATE; ++l)	    e[l]=f[l]=g[l]=h[l]=x[l]=y[l]=~((uint32_t)0);      	  /*---- check that every output bit is affected by that input bit */	  for (k=0; k<MAXPAIR; k+=2)	  { 	    uint32_t finished=1;	    /* keys have one bit different */	    for (l=0; l<hlen+1; ++l) {a[l] = b[l] = (uint8_t)0;}	    /* have a and b be two keys differing in only one bit */	    a[i] ^= (k<<j);	    a[i] ^= (k>>(8-j));	     c[0] = hashlittle(a, hlen, m);	    b[i] ^= ((k+1)<<j);	    b[i] ^= ((k+1)>>(8-j));	     d[0] = hashlittle(b, hlen, m);	    /* check every bit is 1, 0, set, and not set at least once */	    for (l=0; l<HASHSTATE; ++l)	    {	      e[l] &= (c[l]^d[l]);	      f[l] &= ~(c[l]^d[l]);	      g[l] &= c[l];	      h[l] &= ~c[l];	      x[l] &= d[l];	      y[l] &= ~d[l];	      if (e[l]|f[l]|g[l]|h[l]|x[l]|y[l]) finished=0;	    }	    if (finished) break;	  }	  if (k>z) z=k;	  if (k==MAXPAIR) 	  {	     printf("Some bit didn't change: ");	     printf("%.8x %.8x %.8x %.8x %.8x %.8x  ",	            e[0],f[0],g[0],h[0],x[0],y[0]);	     printf("i %d j %d m %d len %d\n", i, j, m, hlen);	  }	  if (z==MAXPAIR) goto done;	}      }    }   done:    if (z < MAXPAIR)    {      printf("Mix success  %2d bytes  %2d initvals  ",i,m);      printf("required  %d  trials\n", z/2);    }  }  printf("\n");}/* Check for reading beyond the end of the buffer and alignment problems */void driver3(){  uint8_t buf[MAXLEN+20], *b;  uint32_t len;  uint8_t q[] = "This is the time for all good men to come to the aid of their country...";  uint32_t h;  uint8_t qq[] = "xThis is the time for all good men to come to the aid of their country...";  uint32_t i;  uint8_t qqq[] = "xxThis is the time for all good men to come to the aid of their country...";  uint32_t j;  uint8_t qqqq[] = "xxxThis is the time for all good men to come to the aid of their country...";  uint32_t ref,x,y;  uint8_t *p;  printf("Endianness.  These lines should all be the same (for values filled in):\n");  printf("%.8x                            %.8x                            %.8x\n",         hashword((const uint32_t *)q, (sizeof(q)-1)/4, 13),         hashword((const uint32_t *)q, (sizeof(q)-5)/4, 13),         hashword((const uint32_t *)q, (sizeof(q)-9)/4, 13));  p = q;  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));  p = &qq[1];  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));  p = &qqq[2];  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));  p = &qqqq[3];  printf("%.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",         hashlittle(p, sizeof(q)-1, 13), hashlittle(p, sizeof(q)-2, 13),         hashlittle(p, sizeof(q)-3, 13), hashlittle(p, sizeof(q)-4, 13),         hashlittle(p, sizeof(q)-5, 13), hashlittle(p, sizeof(q)-6, 13),         hashlittle(p, sizeof(q)-7, 13), hashlittle(p, sizeof(q)-8, 13),         hashlittle(p, sizeof(q)-9, 13), hashlittle(p, sizeof(q)-10, 13),         hashlittle(p, sizeof(q)-11, 13), hashlittle(p, sizeof(q)-12, 13));  printf("\n");  /* check that hashlittle2 and hashlittle produce the same results */  i=47; j=0;  hashlittle2(q, sizeof(q), &i, &j);  if (hashlittle(q, sizeof(q), 47) != i)    printf("hashlittle2 and hashlittle mismatch\n");  /* check that hashword2 and hashword produce the same results */  len = 0xdeadbeef;  i=47, j=0;  hashword2(&len, 1, &i, &j);  if (hashword(&len, 1, 47) != i)    printf("hashword2 and hashword mismatch %x %x\n", 	   i, hashword(&len, 1, 47));  /* check hashlittle doesn't read before or after the ends of the string */  for (h=0, b=buf+1; h<8; ++h, ++b)  {    for (i=0; i<MAXLEN; ++i)    {      len = i;      for (j=0; j<i; ++j) *(b+j)=0;      /* these should all be equal */      ref = hashlittle(b, len, (uint32_t)1);      *(b+i)=(uint8_t)~0;      *(b-1)=(uint8_t)~0;      x = hashlittle(b, len, (uint32_t)1);      y = hashlittle(b, len, (uint32_t)1);      if ((ref != x) || (ref != y))       {	printf("alignment error: %.8x %.8x %.8x %d %d\n",ref,x,y,               h, i);      }    }  }}/* check for problems with nulls */ void driver4(){  uint8_t buf[1];  uint32_t h,i,state[HASHSTATE];  buf[0] = ~0;  for (i=0; i<HASHSTATE; ++i) state[i] = 1;  printf("These should all be different\n");  for (i=0, h=0; i<8; ++i)  {    h = hashlittle(buf, 0, h);    printf("%2ld  0-byte strings, hash is  %.8x\n", i, h);  }}int main(){  driver1();   /* test that the key is hashed: used for timings */  driver2();   /* test that whole key is hashed thoroughly */  driver3();   /* test that nothing but the key is hashed */  driver4();   /* test hashing multiple buffers (all buffers are null) */  return 1;}#endif  /* SELF_TEST */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -