Это довольно легко без каких-либо дополнительных зависимостей, хотя я не даю вам точного ответа, но представляю, как работает IP в целом и как решать вашу проблему.Этот урок будет гораздо более ценным, если вы сделаете это самостоятельно.
Возьмем, к примеру, 10.0.0.0/20
CIDR .Позволяет преобразовать 10.0.0.0
в биты:
00001010.00000000.00000000.00000000
Мы отбрасываем 20 бит, так как это сеть слева, поэтому у нас остается 0000.00000000
для хостов (.
точки приведены здесь только для удобства чтения):
00001010.00000000.00000000.00000000 Network
XXXXXXXX.XXXXXXXX.XXXX0000.00000000 Strip 20 bits of the subnet
Перетасуйте каждый октет оставшимися битами так, как вы хотите, например, мы можем получить 0101.10001010
.Избегайте хоста только с 1
s (1111.11111111
), так как это широковещательный IP-адрес, это все же действительный IP-адрес, хотя не для хостов.Соедините часть подсети с основной частью.Мы получаем:
// S=Subnet, H=Host
SSSSSSSS.SSSSSSSS.SSSSHHHH.HHHHHHHH
00001010.00000000.00000101.10001010
, что составляет 10.0.5.138
.Так как писать было весело, я могу дать вам свою собственную реализацию, которая не требует каких-либо манипуляций со строкамиКак видите, адрес IPv4 представляет собой целое число без знака 2 ^ 32.Таким образом, мы можем применить основную математику.
let ipv4 = {
random: function (subnet, mask) {
// generate random address (integer)
// if the mask is 20, then it's an integer between
// 1 and 2^(32-20)
let randomIp = Math.floor(Math.random() * Math.pow(2, 32 - mask)) + 1;
return this.lon2ip(this.ip2lon(subnet) | randomIp);
},
ip2lon: function (address) {
let result = 0;
address.split('.').forEach(function(octet) {
result <<= 8;
result += parseInt(octet, 10);
});
return result >>> 0;
},
lon2ip: function (lon) {
return [lon >>> 24, lon >> 16 & 255, lon >> 8 & 255, lon & 255].join('.');
}
};
// unit test
console.log(
"192.168.0.35" === ipv4.lon2ip(ipv4.ip2lon('192.168.0.35')) ?
'Test passed' :
'Test failed'
);
for (let i = 0; i < 5; i++) {
console.log(ipv4.random('10.0.0.0', 8));
}