の下IPv4
で、IP アドレスの文字列表現を解析Int32
しINT
、SQL Server
.
今、IPv6
私IPv6
はInt64
?C#
また、人々はそれらの値を のSQL Server
2 つのフィールドとしてどのように保存していますBIGINT
か?
の下IPv4
で、IP アドレスの文字列表現を解析Int32
しINT
、SQL Server
.
今、IPv6
私IPv6
はInt64
?C#
また、人々はそれらの値を のSQL Server
2 つのフィールドとしてどのように保存していますBIGINT
か?
IPv4 アドレスが実際には 32 ビットの数値であるように、IPv6 アドレスは実際には 128 ビットの数値です。アドレスにはさまざまな文字列表現がありますが、実際のアドレスは文字列ではなく数字です。
したがって、IP アドレスを数値に変換するのではなく、アドレスの文字列表現を解析して実際のアドレスに変換します。
a でさえdecimal
128 ビットの数値を保持できないため、次の 3 つの明白な選択肢が残ります。
bigint
2 つのフィールドに分割された数値を格納するvarchar
フィールドに格納するbinary
フィールドに格納するどちらも、IPv4 アドレスを に格納するほど便利ではないint
ため、アドレスで行う必要があることに対する制限を考慮する必要があります。
最も簡単な方法は、フレームワークにこれを実行させることです。IPAddress.Parse
アドレスを解析しIPAddress.GetAddressBytes
、「数値」を byte[] として取得するために使用します。
最後に、2 つの Int64 に変換するために、配列を最初と 2 番目の 8 バイトに分割しMemoryStream
ますBinaryReader
。
これにより、IPv6 アドレスで使用可能なすべてのショートカット表現を理解する必要がなくなります。
SQL Server 2005 を使用している場合は、uniqueidentifier
型を使用できます。このタイプは 16 バイトを格納します。これは、IPv6 IP アドレスに最適です。コンストラクタと を使用して、IPAddress
との間で変換できます。Guid
ToByteArray
IP アドレスを 2 つUInt64
の s (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;
}
データベースに入れる前にUInt64
s をs にキャストしてください。値を元に戻したら、キャストして符号なしの値を取得できます。Int64
ArgumentException
UInt64
逆の処理 (つまり、aUInt64[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']);