js 根据ip区间段生成指定数量的ip及合法性校验

需求

  • 根据IP区间段字符串生成指定数量的ip
  • 检验手动输入的ip是否在指定的ip区间段中;

场景

在一些业务场景中我们前端会根据后端返回的可用ip区间段,自动生成相应数量的ip,因为客户并不关心他的云主句的ip是多少,关心的是ip可用性,提升用户的体验

开发

生成指定数量的IP

代码片段如下:

/**
 * 将数字转为16进制的字符串
 * @param {*} d 
 */
function d2h(d) {
    return d.toString(16)
}

/**
 * 将16进制数字转为10进制
 * @param {*} d 
 */
function h2d(d) {
    return parseInt(d, 16);
}

/**
 * 将ip转数字
 * @param {*} d 
 */
function dot2num(d) {
    var n = d.split(".");
    return 256 * (256 * (256 * +n[0] + +n[1]) + +n[2]) + +n[3]
}

/**
 * 将数字转ip字符串
 * @param {*} d 
 */
function num2dot(d) {
    for (var n = d % 256, t = 3; t > 0; t--)d = Math.floor(d / 256), n = d % 256 + "." + n;
    return n
}

/**
 * 转换函数
 * @param {*} d0 可以是ip字符串也可以是Ip数字
 */
function convert(d0) {
    let d = d0 + '';
    const n = /^(\d|[01]?\d\d|2[0-4]\d|25[0-5])\.(\d|[01]?\d\d|2[0-4]\d|25[0-5])\.(\d|[01]?\d\d|2[0-4]\d|25[0-5])\.(\d|[01]?\d\d|2[0-4]\d|25[0-5])$/, t = /^\d+$/;
    d.match(n) ? d = dot2num(d) : d.match(t) && 4294967296 > +d && (d = num2dot(d));
    return d;
}

function dealIpsToDec(tmpIps, num = 0) {
    const rst = [];
    tmpIps.forEach(o => {
        const oTrim = o.trim(); // 去除首尾空格
        if (/\-/g.test(oTrim)) {
            const [minStr, maxStr] = oTrim.split('-');
            const [min, max] = [convert(minStr), convert(maxStr)];
            const tmpMax = num > 0 && max - min > num ? min + num : max; // 当区间特别大的时候进行处理
            for (let i = min; i <= tmpMax; i++) {
                rst.push(i);
            }
        } else {
            rst.push(convert(oTrim));
        }
    });
    const rstSorted = rst.sort();
    return rstSorted;
}

/**
 * 根据ip区间段生成指定数量的ip
 * @param {*} tmpIps ip区间段
 * @param {*} num 取几个数据
 * @param {*} usedIps 已使用的ip数组
 * @param {*} offSet 偏移量
 */
function generateIpBySort(tmpIps, num, usedIps = [], offSet = 0) {
    const usedIpL = usedIps.length; // 已使用ip数组长度
    const generateIpTotal = num + offSet + usedIpL; // 需要生成ip数组长度+ 偏移量 + 已使用ip长度
    const tmpDecArr0 = dealIpsToDec(tmpIps, generateIpTotal); // 生成ip数组
    const usedIpNum = []; // 已使用ip转化为十进制的数组
    usedIps.forEach(o => usedIpNum.push(convert(o + '')));
    /**
     * 剔除指定的ip
     */
    const tmpDecArr = tmpDecArr0.filter((item) => !(usedIpNum.some((i) => i == item)))

    const rstIps = [];
    const tmpDecArrL = tmpDecArr.length;
    if (tmpDecArrL > 0) {
        const tmpTotal = num + offSet > tmpDecArrL ? tmpDecArrL : num + offSet;
        for (let i = offSet; i < tmpTotal; i++) {
            rstIps.push(convert(tmpDecArr[i]))
        }
    }
    return rstIps;
}

校验IP合法性

当用户自己输入IP时,我们需校验ip的合法性,看是否是合法IP
代码片段

/**
 * 校验ip是否在规定的ip区间段里面
 * @param {*} tmpIps 
 * @param {*} ip 
 * @rst {*} rstFlag 为true表示校验在合法区间,为false为非法IP
 */
function examineIpValidate(tmpIps, ip) {
    const ipTrim = ip.trim(); // 去除首尾空格
    const ipToDec = convert(ipTrim);
    let rstFlag = false;
    for (let o of tmpIps) {
        const oTrim = o.trim(); // 去除首尾空格
        if (/\-/g.test(oTrim)) {
            const [minStr, maxStr] = oTrim.split('-');
            const [min, max] = [convert(minStr), convert(maxStr)];
            if (min <= ipToDec && ipToDec <= max) {
                rstFlag = true;
                break;
            }
        } else {
            if (convert(oTrim) === ipToDec) {
                rstFlag = true;
                break;
            }
        }
    }
    console.log('***********====', rstFlag)
    return rstFlag;
}

测试

const ipList = ["192.168.0.2-192.168.0.5", " 192.168.63.253"];
const ipListRet = generateIpBySort(ipList, 8, ['192.168.0.3']);
console.log(`**********生成指定数量的IP**********`);
console.log(`生成结果如下:${ipListRet}`);
const testArr = [" 192.168.0.38", "192.168.0.7-193.168.0.67", " 192.168.0.34"];
const testIp = ' 192.168.0.38';
console.log(`**********校验IP合法性**********`);
console.log(`校验结果如下:${examineIpValidate(testArr, " 192.168.0.38")}`);

测试结果如下

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值