网络和IP地址计算器方案(js)
ip固定四段组成
IP地址由四段组成,每个字段是一个字节,即4个字节、 每个字节有8位,最大值是255(=256:0~255),是全世界范围是唯一的 32 位(4个字节 * 8位)的标识符。
https://blog.youkuaiyun.com/shengzhu1/article/details/71524278
掩码位
IP地址“/”后面的数字代表的是32位二进制网络掩码中连续“1”的个数。 “/23”代表掩码中有23个1,9个0,化成十进制后的掩码为255.255.254.0。
掩码位可提供的ip
/23 就是 11111111 11111111 11111110 00000000 前23位是1 后边补0
那他可提供的ip 端就是 2的最大可变位 2的9次方 512个
共有9位二进制可以用的IP地址,换算成十进制为(0-511)=512个可用IP;去掉最大的广播IP和最小的网络号IP;可用IP为510个; 具体可用IP为 255.255.254.0 ~~~~255.255.255.255
最大广播号 255.255.255.255 最小广播号255.255.254.0
IP/掩码位
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
ip地址和掩码与运算就得到了网络位
https://blog.youkuaiyun.com/weixin_35728411/article/details/112409842
子网网络号
网络地址和第一个可用网络地址
假设IP地址是 192.168.1.10
,子网掩码是 255.255.255.0
。网络地址将是 192.168.1.0
。
在这个子网中,192.168.1.0
代表整个网络
第一个可用地址是网络地址的下一位(即网络地址的主机部分全部是0,将其加1得到)。这个地址通常是留给网络设备(比如路由器)使用的
源网站(计算不一定对)
https://tool.520101.com/wangluo/ipjisuan/
https://www.sojson.com/convert/subnetmask.html
显示网络,广播,第一次和最后一个给定的网络地址:
/*
* @Author: LiuChuanQi
* @Date: 2024-10-16 15:05:42
* @LastEditTime: 2024-10-17 16:31:26
* @LastEditors: LiuChuanQi
* @Description: 网络和IP地址计算器 显示网络,广播,第一次和最后一个给定的网络地址:
* @FilePath: \ip计算工具\index.js
*
*/
/**
* 判断是否合法ip
* @param {*} ip
* @returns
*/
function isValidIP (ip) {
const ipRegex = /^(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/
return ipRegex.test(ip)
}
/**
* 判断是否是合法的掩码1的个数 1-32
* @param {*} mask
* @returns
*/
function isVaildMask (mask) {
const tmpvar = parseInt(mask, 10)
return !(isNaN(tmpvar) || tmpvar > 32 || tmpvar < 0)
}
// 计算
function h_fillbitsfromleft (num) {
if (num >= 8) {
return (255)
}
bitpat = 0xff00 // 1111 1111 0000 0000
// 最多移动七次 每移动一次右侧丢一位
while (num > 0) {
bitpat = bitpat >> 1
num--
}
//返回最低8位 移动一次就是2的一次方 最大为2的7次方 128
return (bitpat & 0xff)
}
/**
* 掩码的计算
* @param {*} mask
* @returns
*/
function calcNWmask (mask) {
let tmpvar = mask
let maskObj = []
for (let index = 0; index < 3; index++) {
let name = `snm_${index + 1}`
// 每8个1 是一个255的值
if (tmpvar >= 8) {
maskObj.push(255)
tmpvar -= 8
} else {
maskObj.push(h_fillbitsfromleft(tmpvar))
maskObj = maskObj.concat(new Array(4 - maskObj.length).fill(0))
return (maskObj)
}
}
maskObj.push(h_fillbitsfromleft(tmpvar))
return (maskObj)
}
/**
* 计算当前掩码可使用的地址数量
* @param {*} mask
* @returns
*/
function calcAdressNum (mask) {
let tmpvar = mask
let numofaddr = 0
if (tmpvar == 31) {
numofaddr = 2
return numofaddr
}
if (tmpvar == 32) {
numofaddr = 1
return numofaddr
}
// 减2 去掉去掉最大的广播IP和最小的网络号IP
numofaddr = Math.pow(2, 32 - tmpvar) - 2
return numofaddr
}
/**
* 第一个可用网络
* @param {*} ipArr
* @param {*} maskList
* @param {*} tmpvar
* @returns
*/
function calcFirstAdr (ipArr, maskList, tmpvar) {
//第一个可用
let lastArr = []
if (tmpvar == 31) {
for (let index = 0; index < 4; index++) {
let addrItem = ipArr[index] & maskList[index]
lastArr.push(addrItem)
}
return lastArr
}
if (tmpvar == 32) {
for (let index = 0; index < 4; index++) {
let addrItem = ipArr[index]
lastArr.push(addrItem)
}
return lastArr
}
for (let index = 0; index < 4; index++) {
let addrItem = ipArr[index] & maskList[index]
if (index === 3) {
addrItem = parseInt(addrItem) + 1
}
lastArr.push(addrItem)
}
return lastArr
}
/**
* 最后一个可用
* @param {*} ipArr
* @param {*} maskList
* @param {*} tmpvar
* @returns
*/
function calcLastAdr (ipArr, maskList, tmpvar) {
let lastArr = []
if (tmpvar == 31) {
for (let index = 0; index < 4; index++) {
let addrItem = ipArr[index] | (~maskList[index] & 0xff)
lastArr.push(addrItem)
}
return lastArr
}
if (tmpvar == 32) {
return lastArr
}
for (let index = 0; index < 4; index++) {
let addrItem = ipArr[index] | (~maskList[index] & 0xff)
if (index === 3) {
addrItem = parseInt(addrItem) - 1
}
lastArr.push(addrItem)
}
return lastArr
}
//网络地址计算
function calcAdress (ipArr, maskList, tmpvar) {
let lastArr = []
if (tmpvar == 31 || tmpvar == 32) {
// 没有可用网络地址
return lastArr
}
for (let index = 0; index < 4; index++) {
let addrItem = ipArr[index]& maskList[index]
lastArr.push(addrItem)
}
return lastArr
}
// 广播地址计算
function calcBroadCast(ipArr, maskList, tmpvar) {
let lastArr = []
if (tmpvar == 31 || tmpvar == 32) {
// 没有可用广播地址
return lastArr
}
for (let index = 0; index < 4; index++) {
let addrItem = ipArr[index] | (~maskList[index]& 0xff)
lastArr.push(addrItem)
}
return lastArr
}
/**
* 网络Ip 计算器
* 显示网络,广播,第一次和最后一个给定的网络地址:
*/
function calNBFL (ip, mask) {
if (isValidIP(ip) && isVaildMask(mask)) {
let ipArr = ip.split('.').map(item => parseInt(item))
let maskNum = mask
let maskList = calcNWmask(maskNum) //计算掩码
let numofaddr = calcAdressNum(maskNum) //计算可用的地址
let firstadr = calcFirstAdr(ipArr, maskList, maskNum)
let lastadr = calcLastAdr(ipArr, maskList, maskNum)
let networkAdress = calcAdress(ipArr, maskList, maskNum)
let broadCastAdress = calcBroadCast(ipArr, maskList, maskNum)
console.log('输入', ipArr, maskNum)
console.log('可用地址数量', numofaddr)
console.log('掩码', maskList)
console.log('网络地址', networkAdress)
console.log('第一个可用', firstadr)
console.log('最后一个可用', lastadr)
console.log('广播', broadCastAdress)
} else {
console.log('ip或掩码不合法')
}
}
calNBFL('122.10.10.5', 11)
输出
输入 [ 122, 10, 10, 5 ] 11
可用地址数量 2097150
掩码 [ 255, 224, 0, 0 ]
网络地址 [ 122, 0, 0, 0 ]
第一个可用 [ 122, 0, 0, 1 ]
最后一个可用 [ 122, 31, 255, 254 ]
广播 [ 122, 31, 255, 255 ]
IP地址和网络转换器子网掩码转换器(对位点分十进制格式)
/**
* 输入不正确的掩码位时,自动向下校正
* @param {*} decimal
* @returns
*/
function snmcorrect (decimal) {
let snmcorr = decimal
if (decimal > 255) snmcorr = 255
if (decimal == 253) snmcorr = 254
if ((decimal > 248) && (decimal < 252)) snmcorr = 252
if ((decimal > 240) && (decimal < 248)) snmcorr = 248
if ((decimal > 224) && (decimal < 240)) snmcorr = 240
if ((decimal > 192) && (decimal < 224)) snmcorr = 224
if ((decimal > 128) && (decimal < 192)) snmcorr = 192
if ((decimal > 0) && (decimal < 128)) snmcorr = 128
if (decimal < 0) snmcorr = 0
return (snmcorr)
}
/**
* 掩码纠错返回正确掩码
* @param {*} snm1c
* @returns
*/
function computeSNMA (snm1c) {
let newArr = snm1c.split('.').map(item => parseInt(item))
newArr[0] = snmcorrect(newArr[0])
if (newArr[0] < 255) {
newArr[1] = 0
newArr[2] = 0
newArr[3] = 0
} else {
newArr[1] = snmcorrect(newArr[1])
if (newArr[1] < 255) {
newArr[0] = 255
newArr[2] = 0
newArr[3] = 0
} else {
newArr[2] = snmcorrect(newArr[2])
if (newArr[2] < 255) {
newArr[0] = 255
newArr[1] = 255
newArr[3] = 0
} else {
newArr[3] = snmcorrect(newArr[3])
}
}
}
return newArr
}
/**
* 四个掩码转化为多少个连续的1
* @param {*} decimal
* @returns
*/
function d2bits(decimal) {
var bits = 0;
if (decimal & 128) {
bits = bits + 1
}
if (decimal & 64) {
bits = bits + 1
}
if (decimal & 32) {
bits = bits + 1
}
if (decimal & 16) {
bits = bits + 1
}
if (decimal & 8) {
bits = bits + 1
}
if (decimal & 4) {
bits = bits + 1
}
if (decimal & 2) {
bits = bits + 1
}
if (decimal & 1) {
bits = bits + 1
}
return (bits);
}
function computeSNMABIT (snma) {
let bits = 0
for (let index = 0; index < snma.length; index++) {
bits = bits + d2bits(snma[index])
}
return bits
}
function calcNWbits (mask) {
console.log('输入子网掩码', mask)
let snma = computeSNMA(mask)
let snmaBit = computeSNMABIT(snma)
console.log('格式化后的网络掩码', snma)
console.log('掩码位元数', snmaBit)
}
calcNWbits('255.255.128.0')
输出
输入子网掩码 255.255.128.0
格式化后的网络掩码 [ 255, 255, 128, 0 ]
掩码位元数 17
子网掩码转换器(位点分十进制格式)
// 计算
function h_fillbitsfromleft (num) {
if (num >= 8) {
return (255)
}
bitpat = 0xff00 // 1111 1111 0000 0000
// 最多移动七次 每移动一次右侧丢一位
while (num > 0) {
bitpat = bitpat >> 1
num--
}
//返回最低8位 移动一次就是2的一次方 最大为2的7次方 128
return (bitpat & 0xff)
}
/**
* 掩码的计算
* @param {*} mask
* @returns
*/
function calcNWmask (mask) {
let tmpvar = mask
let maskObj = []
for (let index = 0; index < 3; index++) {
// 每8个1 是一个255的值
if (tmpvar >= 8) {
maskObj.push(255)
tmpvar -= 8
} else {
maskObj.push(h_fillbitsfromleft(tmpvar))
maskObj = maskObj.concat(new Array(4 - maskObj.length).fill(0))
return (maskObj)
}
}
maskObj.push(h_fillbitsfromleft(tmpvar))
return (maskObj)
}
/**
* 16进制补0操作
* @param {*} str
* @returns
*/
function h_paddto2(str) {
while(str.length <2){
str= "0" + str;
}
return(str);
}
function h_initArray() {
this.length = h_initArray.arguments.length;
for (var i = 0; i < this.length; i++)
this[i] = h_initArray.arguments[i];
}
/**
* 0-16进制任意转化
* @param {*} value
* @param {*} radix
* @returns
*/
function h_from10toradix(value,radix){
var retval = '';
var ConvArray = new h_initArray(0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F');
var intnum;
var tmpnum;
var i = 0;
intnum = parseInt(value,10);
if (isNaN(intnum)){
retval = 'NaN';
}else{
if (intnum < 1){
retval ="0";
}else{
retval = "";
}
// 避免浮点数精度问题
while (intnum > 0.9){
i++;
tmpnum = intnum;
// cancatinate return string with new digit:
retval = ConvArray[tmpnum % radix] + retval;
intnum = Math.floor(tmpnum / radix);
if (i > 100){
// break infinite loops
retval = 'NaN';
break;
}
}
}
return retval;
}
function hexCalcNWmask (decMask) {
let arr = [0,0,0,0]
for (let index = 0; index < 4; index++) {
arr[index] = h_paddto2(h_from10toradix(decMask[index],16))
}
return arr
}
function calcNWmaskForm2 (mask) {
console.log('掩码位元数', mask)
let decMask = calcNWmask(mask)
let hexMask = hexCalcNWmask(decMask)
console.log('Dec 十进制:',decMask);
console.log('Hex 十六进制:',hexMask);
}
calcNWmaskForm2(17)
输出
掩码位元数 17
Dec 十进制: [ 255, 255, 128, 0 ]
Hex 十六进制: [ ‘FF’, ‘FF’, ‘80’, ‘00’ ]
所需数量掩码地址转换器 需要多少网络地址 给你分配不同的掩码
function isValidNum(num) {
tmpvar = parseInt(num,10);
if (isNaN(tmpvar) || tmpvar > 0xfffffffe || tmpvar < 1) {
return false
}
return true
}
/**
* 掩码的计算
* @param {*} mask
* @returns
*/
function calcNWmask (mask) {
let tmpvar = mask
let maskObj = []
for (let index = 0; index < 3; index++) {
let name = `snm_${index + 1}`
// 每8个1 是一个255的值
if (tmpvar >= 8) {
maskObj.push(255)
tmpvar -= 8
} else {
maskObj.push(h_fillbitsfromleft(tmpvar))
maskObj = maskObj.concat(new Array(4 - maskObj.length).fill(0))
return (maskObj)
}
}
maskObj.push(h_fillbitsfromleft(tmpvar))
return (maskObj)
}
// 计算
function h_fillbitsfromleft (num) {
if (num >= 8) {
return (255)
}
bitpat = 0xff00 // 1111 1111 0000 0000
// 最多移动七次 每移动一次右侧丢一位
while (num > 0) {
bitpat = bitpat >> 1
num--
}
//返回最低8位 移动一次就是2的一次方 最大为2的7次方 128
return (bitpat & 0xff)
}
function calcNeeded (num) {
console.log('需要的地址数量', num)
let expval = 0 //计算指数
let maxaddr = 0 // 可用网址数量 为最大网址数减2
let bits = 0 // 位掩码
if (isValidNum(num)) {
expval=parseInt(Math.log(tmpvar)/Math.log(2)) + 1;
maxaddrval=Math.pow(2,expval);
if (maxaddrval - tmpvar < 2){
expval+=1;
}
maxaddr= Math.pow(2,expval) - 2;
bits = 32 - expval;
console.log('最大网址数量',maxaddrval);
console.log('可用网址数量',maxaddr);
console.log('dotted dec. 掩码',calcNWmask(bits));
console.log('二进制掩码位',bits);
}
}
calcNeeded(17)
输出
需要的地址数量 17
最大网址数量 32
可用网址数量 30
dotted dec. 掩码 [ 255, 255, 255, 224 ]
二进制掩码位 27
点分十进制IP地址掩码转换二进制和十六进制
/**
* 16进制补0操作
* @param {*} str
* @returns
*/
function h_paddto2(str) {
while(str.length <2){
str= "0" + str;
}
return(str);
}
/**
* 二进制补0
* @param {*} str
* @returns
*/
function h_paddto8(str) {
while(str.length <8){
str= "0" + str;
}
return(str);
}
function h_initArray() {
this.length = h_initArray.arguments.length;
for (var i = 0; i < this.length; i++)
this[i] = h_initArray.arguments[i];
}
/**
* 0-16进制任意转化
* @param {*} value
* @param {*} radix
* @returns
*/
function h_from10toradix(value,radix){
var retval = '';
var ConvArray = new h_initArray(0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F');
var intnum;
var tmpnum;
var i = 0;
intnum = parseInt(value,10);
if (isNaN(intnum)){
retval = 'NaN';
}else{
if (intnum < 1){
retval ="0";
}else{
retval = "";
}
// 避免浮点数精度问题
while (intnum > 0.9){
i++;
tmpnum = intnum;
// cancatinate return string with new digit:
retval = ConvArray[tmpnum % radix] + retval;
intnum = Math.floor(tmpnum / radix);
if (i > 100){
// break infinite loops
retval = 'NaN';
break;
}
}
}
return retval;
}
function bits2(decMask) {
let arr = [0,0,0,0]
for (let index = 0; index < 4; index++) {
arr[index] = h_paddto8(h_from10toradix(decMask[index],2))
}
return arr
}
function hex16(decMask) {
let arr = [0,0,0,0]
for (let index = 0; index < 4; index++) {
arr[index] = h_paddto2(h_from10toradix(decMask[index],16))
}
return arr
}
function calcBinBits (mask) {
console.log('输入的十进制掩码', mask)
let makArr = mask.split('.').map(item => parseInt(item))
let bits = bits2(makArr)
let hex = hex16(makArr)
console.log('Bin 二进制', bits)
console.log('Hex十六进制', hex)
}
calcBinBits('134.234.211.12')
输出
输入的十进制掩码 134.234.211.12
Bin 二进制 [ ‘10000110’, ‘11101010’, ‘11010011’, ‘00001100’ ]
Hex十六进制 [ ‘86’, ‘EA’, ‘D3’, ‘0C’ ]
十六进制掩码转换点分十进制IP地址
/**
* 16进制补0操作
* @param {*} str
* @returns
*/
function h_paddto2(str) {
while(str.length <2){
str= "0" + str;
}
return(str);
}
/**
* 二进制补0
* @param {*} str
* @returns
*/
function h_paddto8(str) {
while(str.length <8){
str= "0" + str;
}
return(str);
}
function h_initArray() {
this.length = h_initArray.arguments.length;
for (var i = 0; i < this.length; i++)
this[i] = h_initArray.arguments[i];
}
/**
* 0-16进制任意转化
* @param {*} value
* @param {*} radix
* @returns
*/
function h_from10toradix(value,radix){
var retval = '';
var ConvArray = new h_initArray(0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E','F');
var intnum;
var tmpnum;
var i = 0;
intnum = parseInt(value,10);
if (isNaN(intnum)){
retval = 'NaN';
}else{
if (intnum < 1){
retval ="0";
}else{
retval = "";
}
// 避免浮点数精度问题
while (intnum > 0.9){
i++;
tmpnum = intnum;
// cancatinate return string with new digit:
retval = ConvArray[tmpnum % radix] + retval;
intnum = Math.floor(tmpnum / radix);
if (i > 100){
// break infinite loops
retval = 'NaN';
break;
}
}
}
return retval;
}
function bits2(decMask) {
let arr = [0,0,0,0]
for (let index = 0; index < 4; index++) {
arr[index] = h_paddto8(h_from10toradix(parseInt(decMask.substr(index * 2, 2), 16),2))
}
return arr
}
function dec10(decMask) {
let arr = [0,0,0,0]
for (let index = 0; index < 4; index++) {
arr[index] = parseInt(decMask.substr(index * 2, 2), 16)
}
return arr
}
function dot2hex (mask) {
console.log('输入的十六进制掩码', mask)
let hexValue = h_paddto8(mask.replace(/0x/i,"").substr(0,8))
let bits = bits2(hexValue)
let hex = dec10(hexValue)
console.log('格式化的十六进制掩码', hexValue)
console.log('Bin 二进制', bits)
console.log('点分十进制', hex)
}
dot2hex('86EAD30C')
输出
输入的十六进制掩码 86EAD30C
格式化的十六进制掩码 86EAD30C
Bin 二进制 [ ‘10000110’, ‘11101010’, ‘11010011’, ‘00001100’ ]
点分十进制 [ 134, 234, 211, 12 ]
计算位补一个IP地址(逆)
function invertIp(ipkArr) {
let arr = [0,0,0,0]
for (let index = 0; index < 4; index++) {
arr[index] = ~ ipkArr[index] & 0xff
}
return arr
}
function calcIpInvert (ip) {
console.log('输入的ip', ip);
let ipkArr = ip.split('.').map(item => parseInt(item))
let otherIp = invertIp(ipkArr)
console.log('补位ip', otherIp);
}
calcIpInvert('255.255.240.0')
输出
输入的ip 255.255.240.0
补位ip [ 0, 0, 15, 255 ]
掩码转换到网络可用地址的数量
function calcAmount(num) {
console.log('输入的掩位', num);
let maxaddr = Math.pow(2,32 - num);
let numofaddr = Math.pow(2, 32 - num) - 2;
console.log('可用地址的数量',numofaddr);
console.log('地址总数',maxaddr);
}
calcAmount(17)
输出
输入的掩位 17
可用地址的数量 32766
地址总数 32768