2009-04-21 208 views
5

繼續從this post我有興趣搜索IPv6地址範圍。IPv6地址範圍

在IPv4下,我將能夠確定ISP提供的開始和結束IP地址,並使用這些整數值作爲範圍界限快速搜索數據庫,以查看數據庫中的任何條目是否落入該範圍。

這將如何受到IPv6的影響?互聯網服務提供商是否仍然擁有像現在一樣的IPv6地址?如果您將IPv6地址作爲兩個bigint存儲在SQL Server數據庫中,您將如何有效地搜索這些範圍?

+0

以下帖由[@vinS]提出(https://stackoverflow.com/users/977855/vins)作爲解決你的IPv6問題:HTTPS: //stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses – datv 2017-12-20 06:34:17

回答

8

在範圍中使用IP地址(既不是IPv4也不是IPv6)是不正確的。將IP地址的特定「範圍」進行分組的正確方法是使用前綴(CIDR表示法)或掩碼(過時,僅對IPv4有效,如果嘗試使用非連續掩碼則會發生瘋狂)。

有時你會看到使用IPv4範圍的人(有時甚至是應用程序,家庭路由器等),但這只是錯誤的做法。

使用Classless Inter-Domain Routing (CIDR)你將有一個元組<地址,前綴>,其中地址是一個128位無符號整數和前綴是一個微小的(0..128)無符號整數。前綴表示網絡地址中有多少位最重要的位表示網絡地址,而其他128位前綴最不重要位表示該網絡中的特定主機。因此,例如,2620:0:860:2 ::/64(wikimedia.org)的IPv6「範圍」表示從2620:0:860:2 ::直到2620:0:860: 860:2:FFFF:FFFF:FFFF:FFFF。

您不應該使用兩個「bigint」將這樣的值存儲在數據庫中,而是在單個列中使用任何本機表示形式,除非您想讓開發人員的生活成爲一場噩夢。如果你的DBMS不支持整數這個大,除了替換你的DBMS,我建議使用固定長度的二進制數據列,長度爲16字節。

4

對適當的IPv6地址使用DBMS不會是一個不好的 想法。下面是使用的PostgreSQL,版本8.3的示例:

mydb=> CREATE TABLE Networks (name TEXT, prefix INET); 
CREATE TABLE 
mydb=> INSERT INTO Networks VALUES ('Documentation', '2001:DB8::/32'); 
INSERT 0 1 
mydb=> INSERT INTO Networks VALUES ('ULA', 'FC00::/7'); 
INSERT 0 1 
mydb=> INSERT INTO Networks VALUES ('Orchid', '2001:10::/28'); 
INSERT 0 1 

mydb=> SELECT * FROM Networks; 
name  | prefix  
---------------+--------------- 
Documentation | 2001:db8::/32 
ULA   | fc00::/7 
Orchid  | 2001:10::/28 
(3 rows) 

mydb=> SELECT * FROM Networks WHERE '2001:DB8::dcaf:BAD' << prefix; 
name  | prefix  
---------------+--------------- 
Documentation | 2001:db8::/32 
(1 row) 
+1

PostgreSQL不錯的壯舉。如果只切換DBMS就像拍手一樣簡單:) – 2011-06-11 09:29:55