将IP地址哈希为[0, H)范围内的数字

4 投票
3 回答
3950 浏览
提问于 2025-04-16 21:53

我正在使用Python-2.6,对哈希函数了解得很少。

我想用CRC哈希函数把一个像'128.0.0.5'这样的IP地址哈希成一个范围在[0, H)之间的值。目前我在考虑这样做:

zlib.crc32('128.0.0.5')%H.

这样做可以吗?我有几个问题想请教你们……

  • 如果我哈希'128.0.0.5'和它的二进制形式'0001110101010……',或者不带'.'的形式,这样做有什么不同吗?

  • zlib.crc32返回的是一个带符号的整数。把一个负数对一个正数H取模(%),结果总是会是正数吗?

  • 对H取模会影响哈希函数的效果吗?(我的意思是,这样做是我能在现有空间和使用的xlib.crc32中能做到的最好方法吗?)

谢谢!

3 个回答

2

第1点) 结果会有所不同,但不会影响哈希的质量。

第2点) 结果总是会是一个正数或者零。

第3点) 当你限制可能的桶的数量时,会影响哈希的质量。

一般来说:你的H大概有多大?记住,IPv4地址其实就是一个32位的值。比如192.168.0.1,只是一个更容易让人理解的字节表示方式。所以如果你的H大于4294967295,就不需要进行哈希了。

4

你为什么想把一个IP地址转换成数字呢?其实IP地址本身就已经有数字的表示方式了。比如,你可以使用netaddr这个库来处理。

>>> import netaddr
>>> ip = netaddr.IPAddress('192.168.1.1')
>>> ip.value
3232235777
>>> netaddr.IPAddress(3232235777)
IPAddress('192.168.1.1')
2

如果我对'128.0.0.5'进行哈希处理,或者对它的二进制形式'0001110101010..'进行哈希,或者不带'.'的形式,这有什么区别吗?

其实没什么区别。

zlib.crc32返回的是一个带符号的整数。用一个负数去除以一个正数,结果总是会是正数吗?

是的。

用H取模(%)会影响哈希函数的效果吗?(我的意思是,使用xlib.crc32的情况下,这样做是最好的选择吗?)

你最好利用校验和的所有位数,因为它们缺乏“雪崩效应”。像192.168.1.1192.168.1.2这样的单个位数变化,可能只会在校验和的前几位产生差异,而%只关注最后几位,这样就会导致哈希值碰撞。

撰写回答