最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Calculate IP Range from IP String equal to x.x.x.xx - Stack Overflow

programmeradmin3浏览0评论

How could or would I calculate the range of IP given an IP string like x.x.x.x/x most common cases could be 198.162.1.1/24 but could be anything, in that anything that's legally allowed.

I want to take 198.162.1.1/24 and convert it to 198.162.1.1 - 198.162.1.124 or whatever the equivilant would be legitimately. So trying to figure out how to mathematically and dynamically figure that out with javascript.

How could or would I calculate the range of IP given an IP string like x.x.x.x/x most common cases could be 198.162.1.1/24 but could be anything, in that anything that's legally allowed.

I want to take 198.162.1.1/24 and convert it to 198.162.1.1 - 198.162.1.124 or whatever the equivilant would be legitimately. So trying to figure out how to mathematically and dynamically figure that out with javascript.

Share Improve this question asked Oct 6, 2015 at 20:20 chrischris 36.9k53 gold badges147 silver badges256 bronze badges 3
  • 198.162.1.1/24 would be 198.162.1.1 - 198.162.1.255, right? /24 would be a mask of 255.255.255.0, yes? – gen_Eric Commented Oct 6, 2015 at 20:24
  • Do you understand at all what each part of the ip address represents? Based on your example, it seems like you don't. – Jeff Mercado Commented Oct 6, 2015 at 22:33
  • @JeffMercado admittedly no, your assumption is correct I do not know well enough about how IP Addresses work. But feel free to elaborate further – chris Commented Oct 7, 2015 at 12:30
Add a comment  | 

3 Answers 3

Reset to default 10

Baseaddresse of the subnet: IP-address & (and) netmask.

Highest address: baseaddress filled with 1 instead of zero at the positions where netmask is zero.

e.g.: 198.162.1.1/24 =>

base: 198.162.1.1 and 255.255.255.0

Block 1: 198 and 255 = 198

Block 2: 162 and 255 = 162

Block 3: 1 and 255 = 1

Block 4: 1 and 0 = 0

=> 198.162.1.0.

high: 198.162.1.0 or 0.0.0.255

Block 1, 2 and 3 are the same.

Block 4: 255

=> 198.162.1.255

Now some code (client side 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('.')];
}

console.log(getIpRangeFromAddressAndNetmask("192.168.138.0/23"));
console.log(getIpRangeFromAddressAndNetmask("192.168.138.0/255.255.254.0"));

working jsfiddle: https://jsfiddle.net/kLjdLadv/

Validation is missing. you can do it by your own.

Brief overview on that format. An ip address (IPv4) is a 32-bit number. We often view it in the dotted decimal form where each byte of the 32-bit number is shown in decimal form separated by dots. The address itself can be broken up into two parts, the subnet followed by the address. The number after the slash indicates how many bits the subnet occupies in the address.

To get the start and end range of addresses, you first need to figure out what the subnet is for the address. That part does not change and the address can range from 0 to the max remaining bits.

The easiest way to do this is to convert the ip address to the 32-bit number form, create a bitmask representing the subnet and apply the mask to get the address ranges. The start address, you clear the address bits, the end address, you set the address bits.

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

If you don't mind using something from npm, there's already a library out there that does exactly what you want. First, npm install netmask. Then run this code. I'm using node 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)
})

The output will be the entire range of addresses for that CIDR notation.

发布评论

评论列表(0)

  1. 暂无评论