我有一個數據庫,存儲所有使用過某個功能的用戶的IP號碼(即:投票投票),我想避免同一用戶或IP投票兩次。數據庫存儲IP壓縮
因此,我一直在存儲投票在我的民意調查中的匿名用戶的所有IP。我的數據庫充滿了IP,如123.456.789 ...
但是,這是低效的,是否有單向函數壓縮和IP到一個較短的字符串?
像123.456.798 =>%DA
我有一個數據庫,存儲所有使用過某個功能的用戶的IP號碼(即:投票投票),我想避免同一用戶或IP投票兩次。數據庫存儲IP壓縮
因此,我一直在存儲投票在我的民意調查中的匿名用戶的所有IP。我的數據庫充滿了IP,如123.456.789 ...
但是,這是低效的,是否有單向函數壓縮和IP到一個較短的字符串?
像123.456.798 =>%DA
對於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);
假設你不支持IPv6,IP地址在一個int適合。你真的需要更小的東西?
而且如果你支持IPv6,兩個多頭就可以。仍然看起來很小。
對不起,我一定錯過了什麼。如何將IPv4轉換爲int或IPv6轉換爲兩個整數?我在想像2字節的東西 – somid3 2011-03-28 03:54:50
@somid - 你不能把4字節的數據放在2字節桶中。 – 2011-03-28 03:59:29
IPv4地址是32位。在虛線表示法中,您可以使用最多15個字節的字符串,該字符串仍表示32位(4字節)地址。顯而易見的步驟是將它們轉換爲二進制格式,例如inet_aton
或inet_pton
。後者通常建議用於新代碼,因爲除了IPv4外,它還處理IPv6地址。
如果你需要超越,可能嘗試存儲地址在一個trie中。雖然這並不適合你的普通數據庫模型,但是,除非你真的有lot或匿名用戶,否則
可能不是
可能是不值得的麻煩。
如果您將它們作爲字符串存儲在數據庫中,那麼這樣做會很浪費。在存儲它們之前,可以將它們轉換爲4個字節的整數。
java.net.InetAddress類有一個getByName方法,它將返回一個新的InetAddress對象。在返回的對象上調用getAddress會得到一個地址的字節數組,您可以很容易地將它轉換爲int。
請注意,InetAddress也可以使用IPv6地址,因此您需要確保可以將它們存儲在數據庫中,或者檢查getByName調用返回的InetAddress的類型以確保它是IPv4地址。
這是可逆的嗎? – 2011-03-28 03:58:31
@穆罕默德:是的,它是可逆的。我會用反向代碼更新答案。 – WhiteFang34 2011-03-28 04:00:53