C C++/IDS 개발 - C
IDS 프로젝트 - 정수로 된 IP주소를 해싱
투영
2024. 4. 25. 08:40
C언어의 포인터는 뭐든지 될 수 있다 거의 메타몽급
크기가 넘어가지만 않으면 (넘어가도 ㄱㅊ긴 함 거기에 머가 있는지 알고만 있다면... 이상한 메모리 터치하면 죽을 수도 있음)
이 점을 이용해서 ip주소를 해싱하고 해시테이블의 키로 이용해봅시다
일단 리눅스에 있는 해싱 함수를 살짝 가져다가 내 입맛대로 자료형만 조금 바꿔주었다
원랜 sha256()을 썼는데, 32바이트가 반환되니 이걸 정수로 다시 바꾸기가 애매했다.
/*
* Ozan Yigit's original sdbm hash.
*
* Ugly, but fast. Break the string up into 8 byte units. On the first time
* through the loop get the "leftover bytes" (strlen % 8). On every other
* iteration, perform 8 HASHC's so we handle all 8 bytes. Essentially, this
* saves us 7 cmp & branch instructions.
*
*/
uint32_t hash_func4 (const char *key, int len) { //ub8 이 unsigned 8비트 char
const char *k;
unsigned int n, loop;
if (len == 0)
return (0);
#define HASHC n = *k++ + 65599 * n
n = 0;
k = key;
loop = (len + 8 - 1) >> 3;
switch (len & (8 - 1)) {
case 0:
do {
HASHC;
case 7:
HASHC;
case 6:
HASHC;
case 5:
HASHC;
case 4:
HASHC;
case 3:
HASHC;
case 2:
HASHC;
case 1:
HASHC;
} while (--loop);
}
return (n);
}
uint32_t hashSrcIp (unsigned int srcip) {
return hash_func4((const char *)&srcip, sizeof(srcip));
}
srcip의 주소를 const char *로 형변환하여 hash_fun4()의 key로 넣어주고, 크기는 sizeof()로 해주면 된다.
실제로 해시함수 만드신 분의 주석에 이렇게 적혀있다
>>Ugly, but fast <<
하지만 빨랐죠?