IPv6地址范围

问题描述:

继续从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

在范围中使用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字节。

对适当的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