代码之家  ›  专栏  ›  技术社区  ›  reinhard

T-SQL:检查IP是否与网络掩码匹配

  •  2
  • reinhard  · 技术社区  · 15 年前

    我的SQL Server数据库将IP网络掩码存储为二进制。 我需要一种方法把这些和给定的IP匹配起来

    例如, 是 192.168.21.5 存储在数据库中的网络掩码的一部分?

    的二进制表示 192.16821.5 :

    11000000.10101000.00010101.00000101 (without the dots)
    

    数据库中存储的网络掩码为:二进制(4)和tinyint字段:

    11000000.10101000.00010101.00000000 / 24
    

    (这将是: 192.168.21.0 /24 )所以,前24位 192.16821.5 必须与数据库中的记录匹配。

    我怎么只检查第一个呢 n 二进制字段的位(类似于 LEFT(text, 24) )?

    有什么聪明的方法可以做到这一点吗,也许是按位 AND 是吗?

    4 回复  |  直到 6 年前
        1
  •  7
  •   Vadim K.    15 年前
    declare @address binary(4) -- goal is to check if this address
    declare @network binary(4) -- is in this network
    declare @netmask tinyint   -- with this netmask in /NN format
    
    set @address = 0xC0A81505 -- 192.168.21.5
    set @network = 0xC0A81500 -- 192.168.21.0
    set @netmask = 24
    
    select
      'address matches network/netmask'
    where
      0 = (
          cast(@address as int) ^ cast(@network as int))
          &
          ~(power(2, 32 - @netmask) - 1)
          )
    

    @netmask 必须介于2和32之间。

        2
  •  1
  •   the Tin Man    12 年前

    192.168.21.5 XOR netmask (192.168.21.0) AND 255.255.255.0 (您只需要前24位)应该是全部 0 在“匹配”IP上。

        3
  •  0
  •   David M    15 年前

    这种情况会:

    (0xffffffff - POWER(2, 32 - bits) + 1) & CAST(ip AS int) = CAST(netmask AS int)
    
        4
  •  0
  •   Anabela Mazurek    6 年前

    如果你想让它与蒙版0或1位一起工作,那么你需要将电源(2,32-@netmask)更改为 Power(强制转换(2为bigint),32-@netmask) 拜伊