2009-12-30 114 views
2

我的SQL-Server數據庫將IP網絡掩碼存儲爲二進制。 我需要一種方法來匹配這些與給定的IPT-Sql:檢查IP是否與網絡掩碼匹配

例如, 是192.168.21.5存儲在數據庫中的網絡掩碼的一部分?

192.168.21.5二進制表示:

11000000.10101000.00010101.00000101 (without the dots) 

存儲在DB網絡掩碼是:二進制文件(4)和一個TINYINT字段:

11000000.10101000.00010101.00000000/24 

(這將是:192.168.21.0 /24),所以, 192.168.21.5的前24位必須與數據庫中的記錄相匹配。

我該如何檢查二進制字段的第一個n位(類似於LEFT(text, 24))?

有沒有什麼聰明的方法可以做到這一點,也許按位AND

回答

7
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必須是這意味着只用位> = 24(C類網絡掩碼)工作2和32

1

192.168.21.5 XOR netmask (192.168.21.0) AND 255.255.255.0(您只需要第一個24位)應該是「匹配」IP上的所有0

0

這種情況做的:

(0xffffffff - POWER(2, 32 - bits) + 1) & CAST(ip AS int) = CAST(netmask AS int) 
+0

之間? 可以使它工作,但不是說比特= 16(B類) 但工作比特> 24對於較小的網絡 – reinhard 2009-12-30 19:10:27

+0

剛剛檢查它,它似乎適用於我的任何位數。你得到B級口罩有什麼問題? – 2009-12-31 12:05:18