문제

아래에 IPv4 IP 주소의 문자열 표현을 구문 분석하고 있습니다. Int32 그리고 그들을 보관합니다 INT 에서 SQL Server.

이제 IPv6 나는 문자열 표현을 구문 분석하는 표준이거나 받아 들여진 방법이 있는지 알아 내려고 노력하고 있습니다. IPv6 두 개 Int64 사용 C#?

또한 사람들이 그 가치를 어떻게 저장하고 있습니까? SQL Server - 두 분야로 BIGINT?

도움이 되었습니까?

해결책

IPv4 주소가 실제로 32 비트 번호 인 것처럼 IPv6 주소는 실제로 128 비트 숫자입니다. 주소에는 다른 문자열 표현이 있지만 실제 주소는 문자열이 아닌 숫자입니다.

따라서 IP 주소를 숫자로 변환하지 않으며 주소의 문자열 표현을 실제 주소로 구문 분석합니다.

조차도 decimal 128 비트 번호를 보유 할 수 있으므로 세 가지 명백한 대안을 남깁니다.

  • 숫자 값 분할을 2로 저장하십시오 bigint 필드
  • 주소의 문자열 표현을 a varchar 필드
  • 숫자 값을 16 바이트에 저장하십시오 binary 필드

IPv4 주소를 int, 당신은 주소로해야 할 일에 대한 그들의 한계를 고려해야합니다.

다른 팁

가장 간단한 경로는 프레임 워크가 당신을 위해이를 수행하는 것입니다. 사용 IPAddress.Parse 그러면 주소를 구문 분석합니다 IPAddress.GetAddressBytes "숫자"를 바이트 []로 가져옵니다.

마지막으로, 배열을 첫 번째 및 두 번째 8 바이트로 나누어서 두 개의 int64로 변환합니다. MemoryStream 바이트 어레이를 통해 a BinaryReader.

이는 IPv6 주소에 사용 가능한 모든 단축 표현을 이해할 필요가 없습니다.

SQL Server 2005를 사용하는 경우 uniqueidentifier 유형. 이 유형은 16 바이트를 저장하며 IPv6 IP 주소에 적합합니다. 당신은 사이를 변환 할 수 있습니다 IPAddress 그리고 Guid 생성자를 사용하여 ToByteArray.

IP 주소를 2로 변환하기 위해 다음 방법을 사용합니다. 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 to Int64s 데이터베이스에 넣기 전에 s가 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