列表

详情


BM85. 验证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

输入:

"172.16.254.1"

输出:

"IPv4"

说明:

这是一个有效的 IPv4 地址, 所以返回 "IPv4"

示例2

输入:

"2001:0db8:85a3:0:0:8A2E:0370:7334"

输出:

"IPv6"

说明:

这是一个有效的 IPv6 地址, 所以返回 "IPv6"

示例3

输入:

"256.256.256.256"

输出:

"Neither"

说明:

这个地址既不是 IPv4 也不是 IPv6 地址

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C 解法, 执行用时: 2ms, 内存消耗: 396KB, 提交时间: 2021-02-28

/**
 * 验证IP地址
 * @param IP string字符串 一个IP地址字符串
 * @return string字符串
 */
int check_ip_as_ipv4(char *ip,int len)
{
    int i = 0,val =0,nodeLen =0,nodeNum =0;
    if(len > 15 || len < 7)
    {
        return -1;
    }
    while(i < len)
    {
        if(ip[i] == '.')
        {
            if(i == 0 || ip[i-1]=='.')
                return -1;
            if(val > 255 || val < 0)
            {
                return -2;
            }
            if(val == 0 && nodeLen > 1)
            {
                return -3;
            }
            val = 0;
            nodeLen = 0;
            nodeNum ++;
            if(nodeNum > 4)
                return -4;
            i++;
        }
        else if(ip[i] < '0' || ip[i] > '9')
            return -5;
        if(val == 0 && nodeLen >= 1)
        {
            return -6;
        }
        val = val*10 +(ip[i]-'0');
        nodeLen ++;
        i++;
    }
    return 0;
}
int check_ip_as_ipv6(char *ip,int len)
{
    int i = 0,val =0,nodeLen =0,nodeNum =0,tmpVal = 0;
    if(len > 39 || len < 15)
    {
        return -1;
    }
    while(i < len)
    {
        if(ip[i] == ':')
        {
            if(i == 0 || ip[i-1]==':')
                return -1;
            if(nodeLen > 4)
            {
                return -2;
            }
            if(val ==0 && nodeLen ==4)
                return -3;
            val = 0;
            nodeLen = 0;
            nodeNum ++;
            if(nodeNum > 8)
                return -4;
            i++;
        }
        else if((ip[i] >= '0' && ip[i] <= '9'))
        {
            tmpVal = ip[i]-'0';
        }
        else if(ip[i] >= 'a' && ip[i] <= 'f')
        {
            tmpVal = ip[i]-'a'+10;
        }
        else if(ip[i] >= 'A' && ip[i] <= 'F')
        {
            tmpVal = ip[i]-'A'+10;
        }
        else
        {
            return -6;
        }
        val = val*16 + tmpVal;
        nodeLen ++;
        i++;
    }
    return 0;
}
char* solve(char* IP ) {
    // write code here
    int len = 0,i=0,ret =0;
    if(NULL == IP)
    {
        return NULL;
    }
    len = strlen(IP);
    while(i<len){
        if(IP[i]=='.'){
            ret = check_ip_as_ipv4(IP,len);
            if(0 == ret){
                return "IPv4";}
            break;
        }
        else if(IP[i]==':'){
            ret = check_ip_as_ipv6(IP,len);
            if(0 == ret)
                return "IPv6";
            break;
        }
        i++;
    }
    return "Neither";
}

C++ 解法, 执行用时: 2ms, 内存消耗: 408KB, 提交时间: 2021-10-05

class Solution {
public:
    /**
     * 验证IP地址
     * @param IP string字符串 一个IP地址字符串
     * @return string字符串
     */
    vector<string> split(string s, string dev)
    {
        vector<string> res;
        int it;
        while((it = s.find(dev)) && it != s.npos)
        {
            res.push_back(s.substr(0, it));
            s = s.substr(it + 1);
        }
        res.push_back(s);
        return res;
    }
    bool isIPv4(string IP)
    {
        if(IP.size() < 7 || IP[0] == '.' || IP[IP.length() - 1] == '.') return false;
        
        vector<string> str = split(IP, ".");
        if(str.size() != 4) return false;
        for(int i = 0; i < str.size(); i++)
        {
            if(str[i].size() == 0 || str[i][0] == '0' && str[i].size() >1 || str[i].size() > 3) return false;
            int num = 0;
            for(int j = 0; j < str[i].size(); j++)
            {
                char c = str[i][j];
                if(c < '0' || c > '9') return false;
                num = num * 10 + (c - '0');
                if(num > 255) return false;
            }
        }
        return true;
    }
    
    
    bool isIPv6(string IP)
    {
        if(IP.size() < 15 || IP[0] == ':' || IP[IP.size() - 1] == ':') return false;
        vector<string > str = split(IP, ":");
        if(str.size() != 8) return false;
        for(int i = 0; i < str.size(); i++)
        {
            if(str[i].size() == 0 || str[i].size() > 4) return false;
            for(int j = 0; j < str[i].size(); j++)
            {
                char c = str[i][j];
                if(!((c >='a' && c <= 'f') || (c >='A' && c <= 'F') || (c >='0' && c <= '9'))) return false;
            }
        }
        return true;
    }
    
    
    string solve(string IP) {
        // write code here
        
        if(isIPv4(IP)) return "IPv4";
        if(isIPv6(IP)) return "IPv6";
        return "Neither";
    }
};

C++ 解法, 执行用时: 2ms, 内存消耗: 416KB, 提交时间: 2021-10-03

class Solution {
public:
    /**
     * 验证IP地址
     * @param IP string字符串 一个IP地址字符串
     * @return string字符串
     */
    vector<string> split(string s,string spliter)
    {
        vector<string> ans;
        int it;
        while((it = s.find(spliter)) && it != s.npos)
        {
            ans.push_back(s.substr(0,it));
            s = s.substr(it + 1);
        }
        ans.push_back(s);
        return ans;
    }
    bool isIPv4(string IP)
    {
        ///长度小于7开头或结尾为.都返回false
        if(IP.size() < 7 || IP[0] == '.' || IP[IP.size() - 1] == '.')
            return false;
        //按照.切分
        vector<string> str = split(IP,".");
        //切割后的长度不够4返回false
        if(str.size() != 4) return false;
        for(int i = 0;i < str.size();i++)
        {
            //开头第一个不能是0
            if(str[i].size() == 0 || str[i][0] == '0' && str[i].size() > 1 || str[i].size() > 3)
                return false;
            int num = 0;//转换数字
            for(int j = 0; j < str[i].size();j++)
            {
                char c = str[i][j];
                //必须是数字
                if(c < '0' || c > '9')
                    return false;
                //变化数字
                num = num * 10 + (c - '0');
                //范围0-255,不能超过255
                if(num > 255)
                    return false;
            }
        }
        return true;
    }
    bool isIPv6(string IP)
    {
        //特殊情况
        if(IP.size() < 15 || IP[0] == ':' || IP[IP.size() - 1] == ':')
            return false;
        //按照.切分
        vector<string> str = split(IP, ":");
        //切割后的长度不够8返回false
        if(str.size() != 8) return false;
        for(int i = 0; i < str.size();i++)
        {
            if(str[i].size() == 0 || str[i].size() > 4)
                return false;
            for(int j = 0;j < str[i].size();j++)
            {
                char c = str[i][j];
                ///必须是数字或字母
                if(!((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9')))
                    return false;
            }
        }
        return true;
    }
    string solve(string IP) {
        // write code here
        if(isIPv4(IP)) return "IPv4";
        if(isIPv6(IP)) return "IPv6";
        return "Neither";
    }
};

C++ 解法, 执行用时: 2ms, 内存消耗: 416KB, 提交时间: 2021-09-28

class Solution {
public:
    /**
     * 验证IP地址
     * @param IP string字符串 一个IP地址字符串
     * @return string字符串
     */
    string solve(string IP) {
        // write code here
        if(IP.find('.') != IP.npos){
            //可能为ipv4
            int i = 0;
            int points = 0;
            while(i < (int)IP.size()){
                if(isdigit(IP[i])){
                    if(IP[i] == '0' && isdigit(IP[i+1])){
                        return "Neither";
                    }else{
                        int n = 0;
                        while(isdigit(IP[i])){
                            n = 10*n + IP[i]-'0';
                            i++;
                        }//找到第一个非数字的位置
                        if(n > 255){
                            return "Neither";
                        }
                    }
                }else{
                    if(IP[i] == '.'){
                        points ++;
                    }else{
                        return "Neither";
                    }
                    i++;
                }
            }
            if(points == 3){
                return "IPv4";
            }
        }
        if(IP.find(':') != IP.npos){
            //可能为IPV6
            int i = 0, points = 0;
//             vector<char> words = {'1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f'};
            while(i < (int)IP.size()){
                if(isdigit(IP[i]) || (IP[i] >='a' && IP[i] <='f') || (IP[i]>='A'&& IP[i]<='F')){
                    //找的到
                    int j = i;
                    while(isdigit(IP[j]) || (IP[j] >='a' && IP[j] <='f') || (IP[j] >='A' && IP[j]<='F')){
                        j++;
                    }
                    //j跳到了:或\0
//                     cout<<j<<endl;
                    if(j-i == 1){
//                         cout<<"i"<<IP[i]<<"  j:"<<IP[j]<<endl;
                        if(IP[i] != '0'){
//                             cout<<"111"<<endl;
                            return "Neither";
                        }else{
                            i = j;
                        }
                    }else if(j-i == 4){
                        i = j;
                    }else{
//                         cout<<"222"<<endl;
                        return "Neither";
                    }
                }else{
                    if(IP[i] == ':'){
                        points++;
                        i++;
                    }else{
//                         cout<<"333"<<endl;
                        return "Neither";
                    }
                }
            }
            if(points == 7){
                return "IPv6";
            }else{
//                 cout<<"444"<<endl;
                return "Neither";
            }
        }
        return "Neither";
    }
};

C 解法, 执行用时: 3ms, 内存消耗: 320KB, 提交时间: 2021-06-16

/**
 * 验证IP地址
 * @param IP string字符串 一个IP地址字符串
 * @return string字符串
 */
#include<string.h>
char* solve(char* IP ) {
    // write code here
    int len = strlen(IP),flag = 0,num = 0;
    for(int i = 0;i < len;i ++){
        if(IP[i] == '.'){
            flag = 4;
            break;
        }
        if(IP[i] == ':'){
            flag = 6;
            break;
        }
    }
    if(flag == 4){
        for(int i = 0,j = 0;i < len;i ++){
            if(IP[i] == '.'){
                if(IP[j] == '0')   return "Neither";
                while(j < i){
                    num *= 10;
                    num += IP[j++] - '0';
                }
                if(num <= 0 || num >= 256)   return "Neither";
                num = 0;
                j = i + 1;
            }
        }
        return "IPv4";
    }
    if(flag == 6){
        for(int i = 0,j = 0;i < len;i ++){
            if(IP[i] == ':'){
                if(i == j || i - j > 4)   return "Neither";
                while(j < i){
                    if(!((IP[j] >= '0' && IP[j] <= '9') || (IP[j] >= 'A' && IP[j] <= 'F') || (IP[j] >= 'a' && IP[j] <= 'f'))){
                        return "Neither";
                    }
                    j ++;
                }
                j = i + 1;
            }
        }
        return "IPv6";
    }
    return "Neither";
}

上一题