客户端 IP 地址的最大长度 [重复]

Posted

技术标签:

【中文标题】客户端 IP 地址的最大长度 [重复]【英文标题】:Max length for client ip address [duplicate] 【发布时间】:2010-11-07 18:47:29 【问题描述】:

可能重复:Maximum length of the textual representation of an IPv6 address?

您建议存储客户端 IP 地址的数据库列的最大大小是多少?我现在将它设置为 16,但是我可以获得比 IPv6 等更长的 IP 地址吗?

【问题讨论】:

这里已经介绍过了。检查***.com/questions/1038950/… 实际上,那个帖子不是很有帮助。我们没有使用 Sql Server,这篇文章的答案简洁明了,正是我想要的。 @Andriyev 该帖子仅指 IPv4。 对于以后来这里的任何人 - 如果您有幸使用 Postgres 的能力,他们有一个 built-in IP data type,所以就是这样。 【参考方案1】:

如果您想以标准表示法处理 IPV6,则有 8 组 4 个十六进制数字:

2001:0dc5:72a3:0000:0000:802e:3370:73E4

32 个十六进制数字 + 7 个分隔符 = 39 个字符。

注意:如果您还希望将 IPV4 地址映射为 IPV6 地址,use 45 characters as @Deepak suggests。

【讨论】:

【参考方案2】:

对于 IPv4,您可以存储 IP 地址的 4 个原始字节(IP 地址中句点之间的每个数字都是 0-255,即一个字节)。但是你必须翻译进出数据库,这很麻烦。

IPv6 地址是 128 位的(与 IPv4 地址的 32 位相反)。它们通常写成 8 组 4 个十六进制数字,用冒号分隔:2001:0db8:85a3:0000:0000:8a2e:0370:7334。 39 个字符适合以这种格式存储 IPv6 地址。

编辑:但是,有一个警告,有关 IPv4 映射的 IPv6 地址的详细信息,请参阅@Deepak 的答案。 (正确的最大 IPv6 字符串长度为 45 个字符。)

【讨论】:

一些数据库(至少是 postgres)有一个本地 IP 列类型,并为您进行转换。 我会避免在“一段时间”内将 IPv4 和 IPv6 混合在数据库的同一字段中。 IPv4 仍然是默认标准,并将在未来几年继续使用。在我使用过的遗留应用程序中,当需要将 IPv6 地址添加到数据库时,这是作为一个单独的条目完成的。这允许将期望 IPv4 地址的现有代码留在原地,并允许代码继续仅获取 IPv4 地址。对于代码的新部分,他们可以选择专门从查询中获取 IPv4、IPV6 或混合。 为什么在 IPv6 是 128 位时 39 字节,即最多占用 16 字节 与您不将 IPv4 存储为 4 个字节的原因相同。 如果您打算通过位掩码查询,那么显然存储为字节。如果每行额外的 23 个字节对您来说是个问题,那么显然存储为字节。不知道问题出在哪里。【参考方案3】:

如IPv6 Wikipedia 文章中所述,

IPv6 地址通常写成 八组四位十六进制 数字,其中每组是分开的 用冒号 (:)

一个典型的 IPv6 地址:

2001:0db8:85a3:0000:0000:8a2e:0370:7334

这是 39 个字符长。 IPv6 地址的长度为 128 位,因此您可以使用 binary(16) 列,但我认为我会坚持使用字母数字表示。

【讨论】:

【参考方案4】:

IPv4 使用 32 位,格式为:

255.255.255.255

我想这取决于您的数据类型,无论您是存储为 CHAR 类型的字符串还是使用数字类型。

IPv6 使用 128 位。除非您在其中包含其他信息,否则您的 IP 不会超过此时间。

IPv6 被分组为 4 个十六进制数字,以冒号分隔,例如(来自***):

2001:0db8:85a3:0000:0000:8a2e:0370:7334

如果您愿意,您可以安全地将其存储为 39 个字符的长字符串。不过,还有其他写地址的速记方法。零集可以被截断为单个 0,或者零集可以被双冒号完全隐藏。

【讨论】:

【参考方案5】:

从尝试过所有三种方式的人那里获取...只需使用 varchar(39)

效率稍低的存储远远超过了在插入/更新时转换它并在任何地方显示它时对其进行格式化的任何好处。

【讨论】:

【参考方案6】:

如果您只是将其存储以供参考,则可以将其存储为字符串,但如果您想进行查找,例如,查看 IP 地址是否在某个表中,则需要“规范表示。 "将整个事物转换为(大)数字是正确的做法。 IPv4 地址可以存储为 long int(32 位),但您需要一个 128 位数字来存储 IPv6 地址。

例如,所有这些字符串实际上都是相同的 IP 地址:127.0.0.1、127.000.000.001、::1、0:0:0:0:0:0:0:1

【讨论】:

【参考方案7】:

一般 39 个字符的 IPv6 结构有一个警告。对于 IPv4 映射的 IPv6 地址,字符串可以更长(超过 39 个字符)。一个例子来说明这一点:

IPv6(39 个字符):

ABCD:ABCD:ABCD:ABCD:ABCD:ABCD:ABCD:ABCD

IPv4 映射的 IPv6(45 个字符):

ABCD:ABCD:ABCD:ABCD:ABCD:ABCD:192.168.158.190

注意:最后 32 位(对应于 IPv4 地址)最多需要 15 个字符(因为 IPv4 使用 4 组 1 字节,格式为 0-255 范围内的 4 个十进制数字,用点分隔( . 字符),所以最大值为DDD.DDD.DDD.DDD)。

因此,正确的最大 IPv6 字符串长度为 45。

这实际上是我参加的 IPv6 培训中的一个测验问题。 (我们都回答了 39!)

【讨论】:

在我看来这是不正确的。根据 tools.ietf.org/html/rfc5952#page-10 和 tools.ietf.org/html/rfc4291#section-2.5.5,IPv6 映射地址的长度最多为 22 个字符,因为它们的格式始终为 ::ffff:000.000.000.000,并且必须缩短 我想知道他是否真的按照tools.ietf.org/html/rfc4291#section-2.5.5.1 表示“与ipv6 兼容的ipv4 地址”。我不记得在野外见过那些。 您可能会在测验中争辩说您以 :hex 形式存储 IPv4 而不是 IPv6,其中 39 再次正确。【参考方案8】:

人们在谈论可以将 IP 地址压缩成原始数据的字符。

所以原则上,由于我们只使用 IPv4(32 位)或 IPv6(128 位),这意味着您最多需要 128 位空间,或者 128/8 = 16 字节

这比建议的 39 字节少得多(假设 charset 是 ascii)。

也就是说,您必须将 IP 地址解码并编码到原始数据中,这本身就是一件微不足道的事情(我以前做过,请参阅 phpip2long() 了解 32 位 IP )。

编辑: inet_pton(和它的反面,inet_ntop())可以满足您的需求,并且适用于两种地址类型。但请注意,在 Windows 上,它从 PHP 5.3 开始可用。

【讨论】:

@Elipticalview 我认为您根本没有阅读我的答案。我从来没有在任何地方提到过 45 字节!如果您将任何 IPv4 值(即使是您提到的坏值)转换为原始数据,它们不应超过 4 个字节 - 因为无论您拥有多少个点,它们都应始终为 4 个数字,每个数字最多 255。

以上是关于客户端 IP 地址的最大长度 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用javascript获取客户端的本地IP地址[重复]

Asp.Net MVC3:使用Javascript的客户端IP地址[重复]

如何在servlet java中获取客户端公共IP地址[重复]

如何通过PHP中的IP地址获取时区[重复]

获取访问我的站点的客户端的 MAC 地址和 IP 地址 [重复]

在 WCF 服务 C# 的服务器端获取客户端的 Mac 地址不重复(在 WCF 3.0 中获取客户端 IP 地址)