21

の下IPv4で、IP アドレスの文字列表現を解析Int32INTSQL Server.

今、IPv6IPv6Int64?C#

また、人々はそれらの値を のSQL Server2 つのフィールドとしてどのように保存していますBIGINTか?

4

5 に答える 5

20

IPv4 アドレスが実際には 32 ビットの数値であるように、IPv6 アドレスは実際には 128 ビットの数値です。アドレスにはさまざまな文字列表現がありますが、実際のアドレスは文字列ではなく数字です。

したがって、IP アドレスを数値に変換するのではなく、アドレスの文字列表現を解析して実際のアドレスに変換します。

a でさえdecimal128 ビットの数値を保持できないため、次の 3 つの明白な選択肢が残ります。

  • bigint2 つのフィールドに分割された数値を格納する
  • アドレスの文字列表現をvarcharフィールドに格納する
  • 数値を 16 バイトbinaryフィールドに格納する

どちらも、IPv4 アドレスを に格納するほど便利ではないintため、アドレスで行う必要があることに対する制限を考慮する必要があります。

于 2009-04-21T21:44:38.467 に答える
12

最も簡単な方法は、フレームワークにこれを実行させることです。IPAddress.Parseアドレスを解析しIPAddress.GetAddressBytes、「数値」を byte[] として取得するために使用します。

最後に、2 つの Int64 に変換するために、配列を最初と 2 番目の 8 バイトに分割しMemoryStreamますBinaryReader

これにより、IPv6 アドレスで使用可能なすべてのショートカット表現を理解する必要がなくなります。

于 2009-04-22T09:48:00.880 に答える
4

SQL Server 2005 を使用している場合は、uniqueidentifier型を使用できます。このタイプは 16 バイトを格納します。これは、IPv6 IP アドレスに最適です。コンストラクタと を使用して、IPAddressとの間で変換できます。GuidToByteArray

于 2010-02-23T23:56:42.220 に答える
3

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;
}

データベースに入れる前にUInt64s をs にキャストしてください。値を元に戻したら、キャストして符号なしの値を取得できます。Int64ArgumentExceptionUInt64

逆の処理 (つまり、aUInt64[2]を IP 文字列に変換する) は必要ないので、そのためのメソッドを作成したことはありません。

于 2009-10-29T21:19:39.777 に答える
0
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']);
于 2011-12-04T14:59:22.133 に答える