将IPv6格式化为C#中的int并将其存储在SQL Server中

IPv4我一直在将IP地址的字符串表示解析为Int32 ,并将它们作为INT存储在SQL Server

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

人们如何将这些值存储在SQL Server – 作为BIGINT两个字段?

正如IPv4地址实际上是32位数字一样,IPv6地址实际上是128位数字。 地址有不同的字符串表示forms,但实际地址是数字,而不是字符串。

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

即使是decimal也不能容纳128位数,因此留下了三个明显的替代方案:

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

既不像在int存储IPv4地址那么方便,所以你必须考虑它们对你需要对地址做什么的限制。

最简单的方法是让框架为您完成此操作。 使用IPAddress.Parse解析地址,然后使用IPAddress.Parse将“number”作为byte []。

最后,将数组划分为第一个和第二个8个字节,以便转换为两个Int64,例如,通过在字节数组上创建MemoryStream ,然后通过BinaryReader读取。

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

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

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

 ///  /// 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. ///  /// The IP address to convert. ///  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 byteList = new System.Collections.Generic.List(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; } 

确保在将UInt64放入数据库之前将其转换为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']);