2015-10-06 241 views
1

我怎麼能或者會計算給定一個IP字符串的IP範圍,如x.x.x.x/x最常見的情況可能是198.162.1.1/24,但可以是任何東西,只要是合法允許的。從IP字符串計算IP範圍等於x.x.x.x/x

我想採取198.162.1.1/24並將其轉換爲 198.162.1.1 - 198.162.1.124或任何equivilant將是合法的。所以想要弄清楚如何用數學和動態的方式來解決這個問題。

+0

'198.162.1.1/24'會是'198.162.1.1' - '198.162.1.255',對吧? '/ 24'會是'255.255.255.0'的掩碼,是嗎? –

+0

你完全理解ip地址的每個部分代表什麼?根據你的例子,你似乎沒有。 –

+0

@JeffMercado坦率地說不,你的假設是正確的,我對IP地址的工作方式不太瞭解。但隨意進一步闡述 – chris

回答

1

如果你不介意使用npm的東西,那裏已經有一個庫,它完全符合你的需求。首先,npm install netmask。然後運行此代碼。我正在使用節點4.1.1

"use strict" 

const Netmask = require('netmask').Netmask 

let block = new Netmask('198.162.1.1/24') 
block.forEach((ip, long, index) => { 
    console.log("Next IP is", ip) 
}) 

輸出將是該CIDR表示法的整個地址範圍。

+1

我正面臨與OP類似的問題,但由於我使用Node.js,Netmask庫確實有幫助。謝謝你的建議! – Letokteren

3

子網的基址:IP地址&(和)網絡掩碼。

最高地址:baseaddress在網絡掩碼爲零的位置填充1而不是零。

例如爲:198.162.1.1/24 =>

基:198.162.1.1 and 255.255.255.0

塊1:198 and 255 = 198

塊2:162 and 255 = 162

塊3:1 and 255 = 1

座4:1 and 0 = 0

=> 198.162.1.0。

高:198.162.1.0 or 0.0.0.255

塊1,2和3是相同的。

座4:255

=> 198.162.1.255

現在一些代碼(客戶端JS):

function getIpRangeFromAddressAndNetmask(str) { 
    var part = str.split("/"); // part[0] = base address, part[1] = netmask 
    var ipaddress = part[0].split('.'); 
    var netmaskblocks = ["0","0","0","0"]; 
    if(!/\d+\.\d+\.\d+\.\d+/.test(part[1])) { 
    // part[1] has to be between 0 and 32 
    netmaskblocks = ("1".repeat(parseInt(part[1], 10)) + "0".repeat(32-parseInt(part[1], 10))).match(/.{1,8}/g); 
    netmaskblocks = netmaskblocks.map(function(el) { return parseInt(el, 2); }); 
    } else { 
    // xxx.xxx.xxx.xxx 
    netmaskblocks = part[1].split('.').map(function(el) { return parseInt(el, 10) }); 
    } 
    // invert for creating broadcast address (highest address) 
    var invertedNetmaskblocks = netmaskblocks.map(function(el) { return el^255; }); 
    var baseAddress = ipaddress.map(function(block, idx) { return block & netmaskblocks[idx]; }); 
    var broadcastaddress = baseAddress.map(function(block, idx) { return block | invertedNetmaskblocks[idx]; }); 
    return [baseAddress.join('.'), broadcastaddress.join('.')]; 
} 

工作的jsfiddle:http://jsfiddle.net/kLjdLadv/

驗證缺失。你可以自己做。

1

該格式的簡要概述。一個IP地址(IPv4)是一個32位數字。我們經常以點分十進制形式查看它,其中32位數字的每個字節以點分隔顯示爲十進制形式。地址本身可以分成兩部分,子網和地址。斜槓後面的數字表示子網在地址中佔用的位數。

要獲取地址的開始和結束範圍,首先需要確定子網的地址。該部分不會改變,地址範圍可以從0到最大剩餘位數。

最簡單的方法是將IP地址轉換爲32位數字形式,創建一個表示子網的位掩碼並應用掩碼來獲取地址範圍。起始地址,你清除地址位,結束地址,你設置地址位。

function u(n) { return n >>> 0; } // we need to treat the numbers as unsigned 
function ip(n) { 
    return [ 
     (n >>> 24) & 0xFF, 
     (n >>> 16) & 0xFF, 
     (n >>> 8) & 0xFF, 
     (n >>> 0) & 0xFF 
    ].join('.'); 
} 

var addr = '198.162.1.1/24', 
    m = addr.match(/\d+/g),  // [ '198', '162', '1', '1', '24' ] 
    addr32 = m.slice(0, 4).reduce(function (a, o) { 
     return u(+a << 8) + +o; 
    }),       // 0xc6a20101 
    mask = u(~0 << (32 - +m[4])); // 0xffffff00 
var start = ip(u(addr32 & mask)), // 198.162.1.0 
    end = ip(u(addr32 | ~mask)); // 198.162.1.255 
+0

這是一個_very_簡化說明。請參閱有關IP如何工作和地址的參考。 –