2015-10-06 243 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如何工作和地址的参考。 –