1. 程式人生 > >【計算機網路】驗證兩個ip是否在同一網段

【計算機網路】驗證兩個ip是否在同一網段

今天有一個需求,要驗證使用者的輸入ip 和 某一個環境下的ip/mask是否在同一個網段,準確的說 ip/mask表述的不準確,權威的表述是這個:Classless Inter-Domain Routing

比如使用者填的是: 10.1.1.5
server端返回的ip/mask是這個10.1.1.12/24

我們先解決這個問題,我們都知道,本來ip地址是32位的二進位制數來表示。為了方便我們將分成4個位元組,每個位元組8位,轉換成十進位制來顯示。

10.1.1.5 轉換成二進位制是這樣:
00001010 00000001 00000001 00000101

10.1.1.12 轉換成二進位制是這樣:
00001010 00000001 00000001 00001100

判斷是否在同一個網段的要求就是我們那這兩個ip地址,與子網掩碼做一次 & 與運算,然後判斷結果是否是相等,相等則是屬於同一網段。

10.1.1.12/24 後面這個24則標識了子網掩碼(ipv4 max value is 32,ipv6 max value is 128):

11111111 11111111 11111111 00000000(32位,前24位為1)

我們需要對
00001010 00000001 00000001 00000101 (10.1.1.5)
與掩碼
11111111 11111111 11111111 00000000

做一次 & 操作;


然後對
00001010 00000001 00000001 00001100 (10.1.1.12)
與掩碼
11111111 11111111 11111111 00000000
做一次 & 操作。

最後的結果是一樣,屬於同一網段。

幫助方法:

export const checkIsInSameNetworkSegment= (ip, ipMask)=> {
  let arr = ipMask.split('/'),
    mask = arr[1],
    standardIp = arr[0]
  mask = (0XFFFFFFFF)<<(32- Number(arr[1]))
  let ips = ip.split('.').map(item=>parseInt(item)) //將ip分成4個數字組成的陣列
  let crdIps = standardIp.split('.').map(item=>parseInt
(item)) //將ip分成4個數字組成的陣列 let ipBinary = (ips[0]<<24) | (ips[1]<<16) | (ips[2]<<8) | (ips[3]) let crdIpBinary = (crdIps[0]<<24) | (crdIps[1]<<16) | (crdIps[2]<<8) | (crdIps[3]) return (ipBinary & mask) === (crdIpBinary & mask) }

如果忘記了位運算請看這裡: javascript位運算

其他資料:

網路地址分類(有些問題,請對比wiki和下面的知乎連結)

Classful network(WIKI)

子網掩碼與ip地址有實際關係嗎? - 回答作者: DADAman