【问题标题】:Perfecting SQL binary to IP Address string conversion完善 SQL 二进制到 IP 地址字符串的转换
【发布时间】:2010-09-08 16:57:04
【问题描述】:

我们使用 binary(16) 字段来存储 IP 地址。我们这样做是因为它可以同时保存 IPv4 和 IPv6 地址,并且很容易与 .Net IPAddress 类一起使用。

但是,我创建了以下 SQL 函数来将二进制地址转换为 IP 地址字符串以进行报告。

CREATE FUNCTION fn_ConvertBinaryIPAddressToString
(
    @binaryIP binary(16)
)
RETURNS nvarchar(39)
AS
BEGIN
    DECLARE @ipAsString nvarchar(39)

    -- Is IPv4
    IF (substring(@binaryIP, 5, 1) = 0x00)  <-- Is there a better way?
    BEGIN

        SELECT @ipAsString = CAST(CAST(substring(@binaryIP, 1, 1) AS int) AS nvarchar(3)) + '.' +
        CAST(CAST(substring(@binaryIP, 2, 1) AS int) AS nvarchar(3)) + '.' +
        CAST(CAST(substring(@binaryIP, 3, 1) AS int) AS nvarchar(3)) + '.' +
        CAST(CAST(substring(@binaryIP, 4, 1) AS int) AS nvarchar(3))

    END
    ELSE
    BEGIN
    -- Is IPv6
        -- taken and modified from http://support.microsoft.com/kb/104829
        DECLARE @i int
        DECLARE @length int
        DECLARE @hexstring char(16)

        SELECT @ipAsString = ''
        SELECT @i = 1
        SELECT @length = 16
        SELECT @hexstring = '0123456789ABCDEF'

        WHILE (@i <= @length)
        BEGIN
            DECLARE @tempint int
            DECLARE @firstint int
            DECLARE @secondint int

            SELECT @tempint = convert(int, substring(@binaryIP,@i,1))
            SELECT @firstint = floor(@tempint/16)
            SELECT @secondint = @tempint - (@firstint*16)

            SELECT @ipAsString = @ipAsString + substring(@hexstring, @firstint+1, 1) + substring(@hexstring, @secondint+1, 1)

            IF (@i % 2 = 0)
                SELECT @ipAsString = @ipAsString + ':'

            SELECT @i = @i + 1
       END
    END

    -- Return the result of the function
    RETURN @ipAsString

END
GO

目前,如果 5 字节为 0,我认为它是 IPv4 地址。这是一个安全的假设吗?检查所有剩余字节是否为零更好还是有更好的方法?

EDIT删除了不必要的演员表

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    我想说你也应该存储地址族,或者编码在你的字节数组中,或者作为一个单独的列。如果您将 16 个字节传递给 IPAddress 构造函数,它将构造为 IPv6 地址,因此您还需要检查代码以确定地址系列。直接保留这些信息似乎要容易得多(并且不依赖于关于 IPv6 地址字节的假设)。

    或者使用 varbinary(16),然后您可以检查 (length=4 => IPv4 地址)的长度

    【讨论】:

      猜你喜欢
      • 2011-02-13
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 2018-05-01
      • 2012-04-11
      • 1970-01-01
      • 1970-01-01
      • 2014-06-09
      相关资源
      最近更新 更多