올바르게 설명한대로 해시 함수는 해시 데이터에 따라 다릅니다.
기능은 계산이 용이해야한다 : 3 조건을 준수 - 일반적인 생각은 좋은 해시 함수를 설계합니다. 어쩌면, 좋은 해시를 사용하지 않는 편이 좋지만 해시를 빠르게 계산하고 불균형 한 버킷이나 테이블 경로에서 손실 된 것보다 해싱에 더 많은 시간을 절약 할 수 있습니다.
함수는 테스트 데이터 집합에 올바른 분포 (의사 임의)가 있어야합니다. 좋은 아이디어 - 해시 함수 "snow-crash effect"에서 입력 데이터의 단일 비트를 변경하면 출력 값이 반으로 줄어 듭니다.
외부 입력 데이터의 경우 해시 함수가 "범용"이어야합니다. 즉 충돌 생성을 시도해야합니다.
내가 가장 좋아하는 해시 기능은 다음과 같습니다. 처음 사용하기 전에 임의의 값을 사용하여 테이블 S_block을 초기화해야합니다. 각 프로그램을 실행할 때마다 실행하는 것이 좋습니다.
const unsigned int S_block[256] = { ... };
#define NLF(h, c) (S_block[(unsigned char)(c + h)]^c)
unsigned int hash(const char *key) {
unsigned int h = 0x1F351F35;
char c;
while(c = *key++)
h = ((h << 7) | (h >> (32 - 7))) + NLF(h, c);
h ^= h >> 16;
return h^(h >> 8);
}
실시 예로서, 내 프로그램 emcSSH이 함수의 변화량을 이용하여 참조. htable.c 파일에는 double hashing 알고리즘에 적합한이 함수의 변형이 포함되어 있습니다.
이러한 "해킹"유형은 일반적으로 유용하지 않습니다. 그들은 특별한 경우에 일하지만, 일반적으로 그들은 한 가지 문제 또는 다른 문제로 고통받습니다. 예를 들어, 실수 값의 경우 입력 값의 범위가 매우 작 으면 끔찍할 수 있습니다. 많은 숫자가 동일한 해시 값으로 해석되기 때문입니다. 나는 이것을 너무 광범위하게 결론 짓기로 결정했다. –
입력이 균일하게 분배되지 않으면 실수 입력 예가 문제가됩니다. 임의 입력의 경우에는 괜찮습니다. 범위가 이미 정의되어 있습니다 (0에서 1). 이러한 "해킹"을 사용하는 유일한 이유는 속도입니다. – nesvarbu