JS IP校验IP+掩码计算网络地址、广播地址、可用地址范围
子网掩码/32是什么意思?
一般来说,这/32意味着网络只有一个 IPv4 地址,
所有流量都将直接在具有该 IPv4 地址的设备和默认网关之间传输。
该设备将无法与网络上的其他设备通信。
视为单个主机,单IP
简洁的说,就是:没有子网。
他的最终目的,就是省公网IP
子网掩码不能单独存在,它必须结合IP地址一起使用。
子网掩码是一个32位地址,也是单IP
子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分。
用来分割子网和区分那些ip是同一个网段的,那些不是同一网段的。
在IPv4中,就是点分十进制四组表示法(四个取值从0到255的数字由点隔开,比如255.128.0.0)
另一种更为简短的形式叫做无类别域间路由(CIDR)表示法
IP…
ip=网络号 + 主机号
网络号代表某个完整的范围 [范围]
主机号代表某台独立的主机 [精确地址]
– 在这个范围内某个主机
– 网络号范围越大,容纳的主机越多
为什么要分成ABC类?
解决实际的应用问题,杜绝ip地址的浪费
划分成ABC类后,就知道网络号和主机号的范围了,
A类网络号占一个字节,B类网络号占两个字节,C类网络号占3个字节.
一个字节8位
A类可以划分2^8=255个网络,
每一个网络可以容纳255x255x255=16581375个主机地址
B类可以划分255x255=6535个网络,每个网络可以容纳255x255=6535个主机地址
C类可以划分255x255x255个网络,每个网络可以容纳255个主机地址
子网掩码
ABC类网分类中的网络段+主机段分别占几位的依据就是子网掩码
A类的子网掩码:255.0.0.0
B类的子网掩码:255.255.0.0
C类的子网掩码:255.255.255.0
子网掩码作用:用于识别IP地址中的网络号和主机号的位数
自然划分情况下,A类网络号占一个字节(网络号是占8位),
B类网络号占两个字节(网络号占16位),
C类网络号占三个字节(网络号占32位)。
但是随着ip地址的不够用,需要子网掩码来划分子网,
让网络号的位数可以比较灵活,可以是9位,15位等等,不再是自然划分的位数
子网划分
解决实际的应用问题,杜绝ip地址的浪费。
例如某个公司才需要100台主机,
C类的话可以提供255台主机,造成了155台主机号的浪费
计算
IP 192.168.1.2的二进制为11000000101010000000000100000010(
注:点分十进制IP转二进制时,四个十进制数字转二进制不足8位的用0补足8位),
将11000000101010000000000100000010换算成十进制为3232235778,
得到其整数型IP形式:3232235778。
另一种换算方法:192 × 256^3 + 168 × 256^2 + 1 × 256 + 2 = 3232235778
我们可以在CMD命令行下输入:ping 3232235778 ,会显示跟 ping 192.168.1.2 同样的回显,
说明两者是等价的
根据自己业务需求改造后的代码
循环版本O(n)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//IDC 网关出口
const IDCIP = [
"49.7.199.0/24",
"221.194.172.0/24",
"111.62.37.0/25",
"111.62.104.192/26",
"122.14.229.0/24",
"106.38.226.0/24",
"116.132.239.0/24",
"111.63.61.128/25",
"111.63.211.128/25",
"220.243.131.0/24",
"123.103.48.12/30",
"123.103.49.12/30",
"45.248.239.0/24",
"121.30.179.0/24",
"183.201.126.0/24",
//加数据
"19.7.199.0/24",
"121.194.172.0/24",
"211.62.37.0/25",
"211.62.104.192/26",
"222.14.229.0/24",
"206.38.226.0/24",
"216.132.239.0/24",
"211.63.61.128/25",
"211.63.211.128/25",
"120.243.131.0/24",
"223.103.48.12/30",
"223.103.49.12/30",
"145.248.239.0/24",
"221.30.179.0/24",
"283.201.126.0/24",
//==
"19.7.199.0/14",
"121.194.172.0/14",
"211.62.37.0/15",
"211.62.104.192/16",
"222.14.229.0/14",
"206.38.226.0/14",
"216.132.239.0/14",
"211.63.61.128/15",
"211.63.211.128/15",
"120.243.131.0/14",
"223.103.48.12/10",
"223.103.49.12/10",
"145.248.239.0/14",
"221.30.179.0/14",
"283.201.126.0/14",
//==
"19.7.199.0/15",
"121.194.172.0/15",
"211.62.37.0/16",
"211.62.104.192/17",
"222.14.229.0/15",
"206.38.226.0/15",
"216.132.239.0/16",
"211.63.61.128/16",
"211.63.211.128/16",
"120.243.131.0/15",
"223.103.48.12/11",
"223.103.49.12/11",
"145.248.239.0/15",
"221.30.179.0/15",
"283.201.126.0/15",
//加数据
"221.194.189.0/27",
]
let obj = {}
IDCIP.forEach(ele => {
let key = ele.split('/')
obj[key] = {
ha: 'ha'
}
});
console.log(obj, 'ojb');
const validateIp4 = ip =>
/^((\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))(\.|$)){4}$/.test(ip) ? true : false;
const validateCidr = cidr =>
/^((\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.){3}((\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\/){1}(\d|[1-3]\d)$/.test(
cidr) ? true : false;
const ip4ToInt = ip =>
ip.split('.').reduce((sum, part) => (sum << 8) + parseInt(part, 10), 0) >>> 0;
//数据转化
const catchIP = new Map();
for (let val of IDCIP) {
if (validateCidr(val)) {
const [range, bits] = val.split('/');
const mask = ~(2 ** (32 - bits) - 1);
// catchIP.set((ip4ToInt(range) & mask), mask)
catchIP.set(range, {
mask,
rangeIP: (ip4ToInt(range) & mask)
})
}
}
console.log(catchIP);
const isIDCIP = (params) => {
if (!validateIp4(params)) {
return false
}
for (let [key, val] of catchIP) {
if ((ip4ToInt(params) & val) === (key)) {
return true;
}
}
return false;
}
const isIDCIP2 = (params) => {
if (!validateIp4(params)) {
return false
}
let value = catchIP.get('221.194.189.0')
console.log(value);
if (value) {
// (ip4ToInt(params) & val) === (key)
if( (ip4ToInt(params) & value.mask) === value.rangeIP){
console.log('helelo');
}
}
}
const t0 = performance.now();
let my = 10000;
let num = 0;
// while (num < my) {
// let a = isIDCIP('221.194.189.0')
// console.log(a);
// num += 1;
// }
isIDCIP2('221.194.189.0')
// isIDCIP('221.194.189.0')
const t1 = performance.now();
console.log(t1 - t0, 'milliseconds');
</script>
</body>
</html>
hash版本O(1)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//IDC 网关出口
const IDCIP = [
"49.7.199.0/24",
"221.194.172.0/24",
"111.62.37.0/25",
"111.62.104.192/26",
"122.14.229.0/24",
"106.38.226.0/24",
"116.132.239.0/24",
"111.63.61.128/25",
"111.63.211.128/25",
"220.243.131.0/24",
"123.103.48.12/30",
"123.103.49.12/30",
"45.248.239.0/24",
"121.30.179.0/24",
"183.201.126.0/24",
//加数据
"19.7.199.0/24",
"121.194.172.0/24",
"211.62.37.0/25",
"211.62.104.192/26",
"222.14.229.0/24",
"206.38.226.0/24",
"216.132.239.0/24",
"211.63.61.128/25",
"211.63.211.128/25",
"120.243.131.0/24",
"223.103.48.12/30",
"223.103.49.12/30",
"145.248.239.0/24",
"221.30.179.0/24",
"283.201.126.0/24",
//==
"19.7.199.0/14",
"121.194.172.0/14",
"211.62.37.0/15",
"211.62.104.192/16",
"222.14.229.0/14",
"206.38.226.0/14",
"216.132.239.0/14",
"211.63.61.128/15",
"211.63.211.128/15",
"120.243.131.0/14",
"223.103.48.12/10",
"223.103.49.12/10",
"145.248.239.0/14",
"221.30.179.0/14",
"283.201.126.0/14",
//==
"19.7.199.0/15",
"121.194.172.0/15",
"211.62.37.0/16",
"211.62.104.192/17",
"222.14.229.0/15",
"206.38.226.0/15",
"216.132.239.0/16",
"211.63.61.128/16",
"211.63.211.128/16",
"120.243.131.0/15",
"223.103.48.12/11",
"223.103.49.12/11",
"145.248.239.0/15",
"221.30.179.0/15",
"283.201.126.0/15",
//加数据
"221.194.189.0/27",
]
const validateIp4 = ip =>
/^((\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))(\.|$)){4}$/.test(ip) ? true : false;
const validateCidr = cidr =>
/^((\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\.){3}((\d|[1-9]\d|1\d\d|2([0-4]\d|5[0-5]))\/){1}(\d|[1-3]\d)$/.test(
cidr) ? true : false;
const ip4ToInt = ip =>
ip.split('.').reduce((sum, part) => (sum << 8) + parseInt(part, 10), 0) >>> 0;
//数据转化
const catchIP = new Map();
for (let val of IDCIP) {
if (validateCidr(val)) {
const [range, bits] = val.split('/');
const mask = ~(2 ** (32 - bits) - 1);
// catchIP.set((ip4ToInt(range) & mask), mask)
catchIP.set(range, {
mask,
rangeIP: (ip4ToInt(range) & mask)
})
}
}
console.log(catchIP);
const isIDCIP = (params) => {
if (!validateIp4(params)) {
return false
}
for (let [key, val] of catchIP) {
console.log(key,'????');
if ((ip4ToInt(params) & val) === (key)) {
return true;
}
}
return false;
}
const t0 = performance.now();
let my = 10000;
let num = 0;
// while (num < my) {
// let a = isIDCIP('221.194.189.0')
// console.log(a);
// num += 1;
// }
console.log( isIDCIP('221.194.189.0'));
const t1 = performance.now();
console.log(t1 - t0, 'milliseconds');
</script>
</body>
</html>