2011-03-28 53 views
2

我有一个数据库,存储所有使用过某个功能的用户的IP号码(即:投票投票),我想避免同一用户或IP投票两次。数据库存储IP压缩

因此,我一直在存储投票在我的民意调查中的匿名用户的所有IP。我的数据库充满了IP,如123.456.789 ...

但是,这是低效的,是否有单向函数压缩和IP到一个较短的字符串?

像123.456.798 =>%DA

回答

2

对于IPv4可以压缩的IP地址转换成一个int这样的:

Scanner scanner = new Scanner(ip).useDelimiter("\\."); 
int value = (scanner.nextInt() << 24) | (scanner.nextInt() << 16) 
     | (scanner.nextInt() << 8) | scanner.nextInt(); 

这可太逆转:

String ip = ((value >> 24) & 0xFF) + "." + ((value >> 16) & 0xFF) 
     + "." + ((value >> 8) & 0xFF) + "." + (value & 0xFF); 
+0

这是可逆的吗? – 2011-03-28 03:58:31

+0

@穆罕默德:是的,它是可逆的。我会用反向代码更新答案。 – WhiteFang34 2011-03-28 04:00:53

0

假设你不支持IPv6,IP地址在一个int适合。你真的需要更小的东西?

而且如果你支持IPv6,两个多头就可以。仍然看起来很小。

+0

对不起,我一定错过了什么。如何将IPv4转换为int或IPv6转换为两个整数?我在想像2字节的东西 – somid3 2011-03-28 03:54:50

+0

@somid - 你不能把4字节的数据放在2字节桶中。 – 2011-03-28 03:59:29

1

IPv4地址是32位。在虚线表示法中,您可以使用最多15个字节的字符串,该字符串仍表示32位(4字节)地址。显而易见的步骤是将它们转换为二进制格式,例如inet_atoninet_pton。后者通常建议用于新代码,因为除了IPv4外,它还处理IPv6地址。

如果你需要超越,可能尝试存储地址在一个trie中。虽然这并不适合你的普通数据库模型,但是,除非你真的有lot或匿名用户,否则 可能不是 可能是不值得的麻烦。

2

如果您将它们作为字符串存储在数据库中,那么这样做会很浪费。在存储它们之前,可以将它们转换为4个字节的整数。

java.net.InetAddress类有一个getByName方法,它将返回一个新的InetAddress对象。在返回的对象上调用getAddress会得到一个地址的字节数组,您可以很容易地将它转换为int。

请注意,InetAddress也可以使用IPv6地址,因此您需要确保可以将它们存储在数据库中,或者检查getByName调用返回的InetAddress的类型以确保它是IPv4地址。