php的关联数组是用hashtable实现的,写了一个测试程序测试php hash表的分布情况
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef unsigned long ulong;
typedef unsigned int uint;
ulong time33(const char* hashstr,uint len);
void randstr(uint len, char *val);
char ** randstrs(uint len,uint keylen);
int main(int argc, char * argv[])
{
char **head;
uint len = 1024;
uint i = 0;
uint mask = len - 1;
ulong hash;
srand((ulong)time(NULL));
head = randstrs(len,8);
for (; i < len; i++){
hash = time33(head[i], strlen(head[i]));
printf("%s\t%10u\t%u\n", head[i], hash, hash & mask);、
free(head[i]);
}
free(head);
system("pause");
return 0;
}
char ** randstrs(uint len, uint keylen)
{
char **head;
int i = 0;
head = (char **)calloc(sizeof(char *), len);
for (; i < len; i++){
head[i] = (char *)malloc(sizeof(char)* (keylen+1));
memset(head[i], '\0', keylen + 1);
randstr(8, head[i]);
}
return head;
}
void randstr(uint len, char *val)
{
char *sourcestr = "abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
size_t sourcelen = strlen(sourcestr);
if (val == NULL) return;
char *temp = (char *)malloc(sizeof(char)* len);
char *head = temp;
for (; len > 0; len--){
*temp++ = sourcestr[rand() % sourcelen];
}
memcpy(val, head, temp-head);
free(head);
}
/************************************************************************/
/* 生成hash值 */
/************************************************************************/
ulong time33(const char* hashstr,uint len )
{
register ulong hash = 5381;
for (; len >= 8; len -= 8){
hash = (hash << 5 + hash) + *hashstr++;
hash = (hash << 5 + hash) + *hashstr++;
hash = (hash << 5 + hash) + *hashstr++;
hash = (hash << 5 + hash) + *hashstr++;
hash = (hash << 5 + hash) + *hashstr++;
hash = (hash << 5 + hash) + *hashstr++;
hash = (hash << 5 + hash) + *hashstr++;
hash = (hash << 5 + hash) + *hashstr++;
}
switch (len){
case 7:hash = (hash << 5 + hash) + *hashstr++;
case 6:hash = (hash << 5 + hash) + *hashstr++;
case 5:hash = (hash << 5 + hash) + *hashstr++;
case 4:hash = (hash << 5 + hash) + *hashstr++;
case 3:hash = (hash << 5 + hash) + *hashstr++;
case 2:hash = (hash << 5 + hash) + *hashstr++;
case 1:hash = (hash << 5 + hash) + *hashstr++; break;
case 0: break;
default:break;
}
return hash;
}
字串 hash值 hash分布区间