在下面 IPv4 我一直在解析IP地址的字符串表示形式 Int32 并将它们存储为 INT 在里面 SQL Server.

现在,有 IPv6 我试图找出是否有标准或接受的方法来解析字符串表示形式 IPv6 到两个 Int64 使用 C#?

还有人们如何将这些价值存储在 SQL Server - 作为两个领域 BIGINT?

有帮助吗?

解决方案

就像IPv4地址实际上是32位数字一样,IPv6地址实际上是128位。地址有不同的字符串表示形式,但实际地址是数字,而不是字符串。

因此,您不会将IP地址转换为一个数字,而是将地址的字符串表示形式解析为实际地址。

甚至没有 decimal 可以容纳128位的数字,因此可以留下三个明显的选择:

  • 将数字值分为两个 bigint 字段
  • 将地址的字符串表示形式存储在 varchar 场地
  • 将数字值存储在16个字节中 binary 场地

都不像将IPv4地址存储在 int, ,因此您必须考虑他们的局限性,而不是您需要处理的地址。

其他提示

最简单的路线是获取框架为您做到这一点。利用 IPAddress.Parse 解析地址,然后 IPAddress.GetAddressBytes 将“数字”作为字节[]。

最后,将数组分为第一个和第二8个字节,以转换为两个INT64,例如创建一个 MemoryStream 在字节阵列上,然后通过 BinaryReader.

这避免了需要了解IPv6地址的所有可用捷径表示形式。

如果您使用的是SQL Server 2005,则可以使用 uniqueidentifier 类型。此类型存储16个字节,非常适合IPv6 IP地址。您可以在之间转换 IPAddressGuid 通过使用构造函数和 ToByteArray.

我使用以下方法将IP地址转换为两个 UInt64S(C#3.0)。

/// <summary>
/// Converts an IP address to its UInt64[2] equivalent.
/// For an IPv4 address, the first element will be 0,
/// and the second will be a UInt32 representation of the four bytes.
/// For an IPv6 address, the first element will be a UInt64
/// representation of the first eight bytes, and the second will be the
/// last eight bytes.
/// </summary>
/// <param name="ipAddress">The IP address to convert.</param>
/// <returns></returns>
private static ulong[] ConvertIPAddressToUInt64Array(string ipAddress)
{
    byte[] addrBytes = System.Net.IPAddress.Parse(ipAddress).GetAddressBytes();
    if (System.BitConverter.IsLittleEndian)
    {
        //little-endian machines store multi-byte integers with the
        //least significant byte first. this is a problem, as integer
        //values are sent over the network in big-endian mode. reversing
        //the order of the bytes is a quick way to get the BitConverter
        //methods to convert the byte arrays in big-endian mode.
        System.Collections.Generic.List<byte> byteList = new System.Collections.Generic.List<byte>(addrBytes);
        byteList.Reverse();
        addrBytes = byteList.ToArray();
    }
    ulong[] addrWords = new ulong[2];
    if (addrBytes.Length > 8)
    {
        addrWords[0] = System.BitConverter.ToUInt64(addrBytes, 8);
        addrWords[1] = System.BitConverter.ToUInt64(addrBytes, 0);
    }
    else
    {
        addrWords[0] = 0;
        addrWords[1] = System.BitConverter.ToUInt32(addrBytes, 0);
    }
    return addrWords;
}

确保您投射 UInt64S到 Int64在将它们放入数据库之前,或者您将获得一个 ArgumentException. 。当您恢复价值时,您可以将它们归还给 UInt64 获得未签名的值。

我不需要进行反向(即转换一个 UInt64[2] 到IP字符串),所以我从未为它构建一种方法。

function encode_ip ($ip)
{
    return bin2hex(inet_pton($ip));
}

function decode_ip($ip)
{
    function hex2bin($temp) {
       $data="";
       for ($i=0; $i < strlen($temp); $i+=2) $data.=chr(hexdec(substr($temp,$i,2)));
       return $data;
    }
    return inet_ntop(hex2bin($ip));
}

-- max len row db
echo strlen(inet_pton('2001:db8:85a3::8a2e:370:7334'));

-- db row info
ip varchar(16)

-- sql binary save and read
save base
$bin_ip='0x'.bin2hex(inet_pton($data['ip_address']));

-- db read
select ip_address from users;

-- encode binary from db
echo inet_ntop($row['ip_address']);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top