85、美团算法题---验证ip地址

该博客主要介绍了如何编写函数来验证输入的字符串是否为有效的IPv4或IPv6地址。针对IPv4,需要确保地址由四个0-255的十进制数构成,不以0开头;对于IPv6,地址应由8组1-4位的十六进制数组成,允许0开头但不能有连续的::。博主提供了两种方法,一种是利用正则表达式,另一种是通过分治法逐块验证地址的合法性。
摘要由CSDN通过智能技术生成

验证IP地址_牛客题霸_牛客网

一、题目

编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址。

IPv4 地址:

  • 由 十进制数 和 点 来表示每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1;
  • 同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。


IPv6 地址:

  • 由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如,  2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址;
  • 而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。
  • 然而,我们不能因为某个组的值为 0,而使用一个空的组,以至于出现 (::) 的情况。 比如, 2001:0db8:85a3::8A2E:0370:7334 是无效的 IPv6 地址。
  • 同时,在 IPv6 地址中,多余的 0 也是不被允许的。比如,02001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。

说明: 你可以认为给定的字符串里没有空格或者其他特殊字符。

 

 

 

二、思路

三、实现 

(1)方法一:使用正则判断

史上最全正则表达式语法,文末附常用表达式!_藏经阁-CSDN博客_正则表达式语法

/**
 * 验证IP地址
 * @param IP string字符串 一个IP地址字符串
 * @return string字符串
 */
function solve( IP ) {
    //1. IPv4: 
    //一位时:为0 或 非零数字;多位时,为[1-9]范围内的数字; 并且数字<256
    let ipv4 = IP.split(".");
    if(ipv4.length===4 && ipv4.every(item => /^0$|^[1-9]\d{0,2}$/.test(item) && item<256)){
        return 'IPv4';
    }
    
    //2. IPv6
    //四位,取值范围为[0-9]、[A-F]、[a-f]
    let ipv6 = IP.split(":");
    if(ipv6.length===8 && ipv6.every(item => /^[0-9A-Fa-f]{1,4}$/.test(item))){
        return 'IPv6';
    }
    
    //3. 其它
    return "Neither"
    
}
module.exports = {
    solve : solve
};

d:匹配数字

^:匹配字符串的开始

$:匹配字符串的结束

{n,m}:重复n到m次

\d{3,6}:匹配3到6位数字

+:重复一次或更多次

[1-9]:限定1到9 

[a-f]:限定a到f

^[A-Za-z0-9]+$ :由数字和26个英文字母组成的字符串

(2)方法二:分治法

IPv4 和 IPv6 地址均是由特定的分界符隔开的字符串组成,并且每个子字符串具有相同格式。

因此,可以将地址分为多个块,然后逐块进行验证。

算法

  1. 对于 IPv4 地址,通过界定符 . 将地址分为四块;对于 IPv6 地址,通过界定符 : 将地址分为八块。
  2. 对于 IPv4 地址的每一块,检查它们是否在 0 - 255 内,且没有前置零。
  3. 对于 IPv6 地址的每一块,检查其长度是否为 1 - 4 位的十六进制数。

 

/**
 * 验证IP地址
 * @param IP string字符串 一个IP地址字符串
 * @return string字符串
 */
function solve( IP ) {
    //1. IP中有三个 点 IPv4
    if(IP.split("").filter(ch => ch==".").length ===3){
        return validateIPv4(IP);
    }else if(IP.split("").filter(ch => ch==":").length === 7){
        //2. IP中有7个冒号  IPv6
        return validateIPv6(IP);
    }else{
        return "Neither"
    }
}
function validateIPv4(ip){
    //判断是否在 0 - 255 内,且没有前置零
    let arr = ip.split(".");
    for(let i=0;i<arr.length;i++){
        if(arr[i].length<=0 || arr[i].length>3){//1. 长度不在1-3范围内
            return "Neither"
        }
        if(arr[i][0]=='0' && arr[i].length>1){//2. 存在前置0
            return "Neither"
        }
        if(isNaN(arr[i]) || arr[i]-'0'<0 || arr[i]-'0'>255){ //3.非数字 或 数字范围不合法
            return "Neither"
        }
    }
    return "IPv4"
}
function validateIPv6(ip){
    let arr = ip.split(":");
     let str = "0123456789abcdefABCDEF";
    for(let i=0;i<arr.length;i++){
        if(arr[i].length<=0 || arr[i].length>4){ //1. 每组数字位数为1~4位
            return "Neither"
        }
//         if(arr[i]=="00" || arr[i]=="000" || arr[i]=="0000"){ //2. 存在多余的0(允许存在多余零)
//             return "Neither"
//         }
        //3. 存在不合法字符
//         arr[i] = parseInt("0x"+arr[i]);
//         if(arr[i]>65535 || arr[i]<0) return "Neither"
        if(arr[i].split("").some(value => {return str.indexOf(value)==-1})){
            return "Neither"
        }
    }
    return "IPv6"
}
module.exports = {
    solve : solve
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值