检查给定字符串是否可以是有效 IP 地址的建议/帮助/更好的解决方案

josh_3501

老实说,我认为我写的代码很垃圾,我认为这不是解决问题的最佳方法。我需要一些建议或改进来解决这个问题。我仍然是编码的新手。如果您能提供一些有关如何使用字符串和各种字符串函数的提示,请欣赏它。

字符串成为 IP 地址的条件:-

连接到 Internet 的设备的标识号。以点分四元表示法编写的 IPv4 地址由四个用句点分隔的 8 位整数组成。

换句话说,它是一个由四个数字组成的字符串,每个数字都在 0 到 255 之间,并带有一个“。” 每个数字之间的字符。所有数字都应该存在,没有前导零。

例子:

  1. 192.168.0.1 是有效的 IPv4 地址
  2. 255.255.255.255 是有效的 IPv4 地址
  3. 280.100.92.101 不是有效的 IPv4 地址,因为 280 太大而不能成为 8 位整数(最大的 8 位整数是 255)
  4. 255.100.81.160.172 不是有效的 IPv4 地址,因为它包含 5 个整数而不是 4 个
  5. 1..0.1 不是有效的 IPv4 地址,因为它的格式不正确
  6. 17.233.00.131 和 17.233.01.131 不是有效的 IPv4 地址,因为它们包含前导零

这是我的代码(我知道这是垃圾,没有任何意义):-

bool isIPv4Address(char * inputString) {
    int count = 0, period = 0;
    int k = 0, i = 0;
    int digit = 0;
    
     
    while(inputString[i] != '\0')
    { 
        count = 0;
        digit = 0;
        i = k;
        
        if(inputString[i] == '0' || inputString[i] == '.')
        {
            if(inputString[i+1] >47 && inputString[i+1] < 58)
            {
                return false;
            }
        }
        
        while(inputString[i] != '.' && inputString[i] != '\0')
        {
            if(inputString[i] < 48 || inputString[i] > 57)
            {
                return false;
            } 
            count += (int)inputString[i];
            i++;
            digit++;
        }
        
        if(digit == 3)
        {
            if(inputString[i - 3] > '2')
            {
                return false;
            }
        }
        
        if(inputString[i] == '.')
        {
            period++;
        }
        
        k = i+1;
      
        if(count < 48 || count > 156)
        {
            return false;
        }
        
        if(inputString[i] == '\0')
        {
            break;
        }
    }
    
    if(period == 3)
    {
        return true;
    }else
    {
        return false;
    }  
}
克雷格·埃斯蒂

你有很多松散的 47、48 等值'0'最好使用后一种语法。

有许多if范围检查。使用一些额外的状态变量可以降低复杂性。

inputString[i]到处使用很麻烦。更好的做法(例如int chr = inputString[i];,改用chr它——它更简单、更易于阅读)。

原始程序错误识别为:

192.168.0.1
280.100.92.101

我重构了代码并构建了一个诊断测试程序。注释为:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

#define ERR(_expr) \
    if (err != NULL) \
        break; \
    if (_expr) { \
        err = #_expr; \
        break; \
    }

const char *bigerr;
int opt_i;

bool
isfix1(const char *inputString)
{
    int i = 0;
    int ndig = -1;
    int ndot = 0;
    int val = 0;
    int leading_zero = 0;
    unsigned char ipv[4];
    const char *err = NULL;

    while (1) {
        int chr = inputString[i++];
        int eos = (chr == 0);

        // check the last number we got
        if ((chr == '.') || eos) {
            ERR(ndig == 0);

            // we don't allow (because it might be decoded as octal):
            //   x.00.y.z x.01.y.z
            // but this must be ok:
            //   x.0.y.z
            ERR(leading_zero && (ndig > 1));

            // we can only have 3 dots in the string
            ndot += (! eos);
            ERR(ndot > 3);

            ndig = 0;
            val = 0;

            if (eos) {
                // we must have _exactly 3 dots in the string
                ERR(ndot != 3);
                break;
            }
            continue;
        }

        // collect digits
        if ((chr >= '0') && (chr <= '9')) {
            val *= 10;
            chr -= '0';
            val += chr;

            if (ndig < 0)
                ndig = 0;

            // remember whether substring started with "0"
            if (ndig == 0)
                leading_zero = (chr == 0);

            // we can only have up to 3 digits per byte
            ++ndig;
            ERR(ndig > 3);

            // max value for byte
            ERR(val > 255);

            // just for fun -- the binary IP address
            ipv[ndot] = val;
            continue;
        }

        // any invalid character
        ERR(chr != 0);
    }

    if (0)
        printf("IPV: %d.%d.%d.%d\n",ipv[0],ipv[1],ipv[2],ipv[3]);

    bigerr = err;

    return (err == NULL);
}

bool
isorig(const char *inputString)
{
    int count = 0,
        period = 0;
    int k = 0,
        i = 0;
    int digit = 0;

    while (inputString[i] != '\0') {
        count = 0;
        digit = 0;
        i = k;

        if (inputString[i] == '0' || inputString[i] == '.') {
            if (inputString[i + 1] > 47 && inputString[i + 1] < 58) {
                return false;
            }
        }

        while (inputString[i] != '.' && inputString[i] != '\0') {
            if (inputString[i] < 48 || inputString[i] > 57) {
                return false;
            }
            count += (int) inputString[i];
            i++;
            digit++;
        }

        if (digit == 3) {
            if (inputString[i - 3] > '2') {
                return false;
            }
        }

        if (inputString[i] == '.') {
            period++;
        }

        k = i + 1;

        if (count < 48 || count > 156) {
            return false;
        }

        if (inputString[i] == '\0') {
            break;
        }
    }

    if (period == 3) {
        return true;
    }
    else {
        return false;
    }
}

int
dofnc(bool (*fnc)(const char *),const char *ipaddr,const char *reason)
{
    int valid;

    bigerr = NULL;

    valid = fnc(ipaddr);
    printf("%s",valid ? "valid" : "INVALID");

    if (bigerr != NULL)
        printf(" (%s)",bigerr);

    printf(" (%s)\n",(valid != (reason == NULL)) ? "FAIL!" : "pass");

    return valid;
}

void
dotest(const char *ipaddr,const char *reason)
{
    static int sep = 0;

    if (sep)
        printf("\n");
    sep = 1;

    printf("IPADDR: %s",ipaddr);
    if (reason != NULL)
        printf(" -- %s",reason);
    printf("\n");

    int valid[2];
    printf("isorig: ");
    valid[0] = dofnc(isorig,ipaddr,reason);
    printf("isfix1: ");
    valid[1] = dofnc(isfix1,ipaddr,reason);

    do {
        if (opt_i)
            break;

        for (int idx = 0;  idx < 2;  ++idx) {
            if (valid[idx] != (reason == NULL))
                exit(1);
        }
    } while (0);
}

int
main(int argc,char **argv)
{

    --argc;
    ++argv;

    for (;  argc > 0;  --argc, ++argv) {
        char *cp = *argv;
        if (*cp != '-')
            break;

        cp += 2;
        switch (cp[-1]) {
        case 'i':
            opt_i = ! opt_i;
            break;
        }
    }

    dotest("192.168.0.1",NULL);
    dotest("255.255.255.255",NULL);
    dotest("280.100.92.101","280 is too large to be an 8-bit integer");
    dotest("255.100.81.160.172","contains 5 integers instead of 4");
    dotest("1..0.1","not properly formatted");
    dotest("1.0.1.","not properly formatted");
    dotest("17.233.00.131","contain leading zeros");
    dotest("17.233.01.131","contain leading zeros");

    return 0;
}

这是程序输出:

IPADDR: 192.168.0.1
isorig: INVALID (FAIL!)
isfix1: valid (pass)

IPADDR: 255.255.255.255
isorig: valid (pass)
isfix1: valid (pass)

IPADDR: 280.100.92.101 -- 280 is too large to be an 8-bit integer
isorig: valid (FAIL!)
isfix1: INVALID (val > 255) (pass)

IPADDR: 255.100.81.160.172 -- contains 5 integers instead of 4
isorig: INVALID (pass)
isfix1: INVALID (ndot > 3) (pass)

IPADDR: 1..0.1 -- not properly formatted
isorig: INVALID (pass)
isfix1: INVALID (ndig == 0) (pass)

IPADDR: 1.0.1. -- not properly formatted
isorig: INVALID (pass)
isfix1: INVALID (ndig == 0) (pass)

IPADDR: 17.233.00.131 -- contain leading zeros
isorig: INVALID (pass)
isfix1: INVALID (leading_zero && (ndig > 1)) (pass)

IPADDR: 17.233.01.131 -- contain leading zeros
isorig: INVALID (pass)
isfix1: INVALID (leading_zero && (ndig > 1)) (pass)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从原始IP字符串计算所有有效IP地址

在Golang中检查IP地址切片中IP的有效方法

Javascript的评估顺序是否有更好的解决方案?

检查给定的输入是否是有效的IP或主机名或无效的名称

从字符串数组中选择有效的IP

更好地理解查找字符串排列的解决方案-javascript

是否嵌套-可能有更好的解决方案?

有什么比蛮力更好的解决方案呢?

有没有比forceUpdate()更好的解决方案

检查用户输入的有效IP地址

javascript:基于数组,有效的解决方案替换字符串中的值

在Java中线性搜索给定的字符串?有更好的解决方案吗?

LPCWSTR错误;有更好的解决方案吗?

如何有效地将字符串用作Java中的WeakHashMap键或替代解决方案

在scala中生成给定字符串的所有IP地址

如何批量检查存储在变量中的字符串是否与netstat -nao的IP地址相同

A *:使用给定的解决方案为15平方拼图找到更好的解决方案

使用静态IP时Internet无法正常工作。当前没有解决方案

静态继承:可能吗?有更好的解决方案吗?

添加字符串的子字符串 IP 地址生成错误但有效

有效 IP 字符串中的“:”是否足以确定它是 IPv6 地址?

Python:检查列表中是否有任何子字符串的优雅解决方案?

为什么我不能通过 SSH 连接到我可以成功 ping 的 IP 地址?(mssfix 不能作为解决方案)

搜索字符串的非蛮力建议解决方案

嵌套函数有问题,或寻找更好解决方案的指导

BLoC 和多个流 - 有更好的解决方案吗?

c# 是否有更简单的 hex2ip 解决方案

有更好的解决方案吗?

是否有通配符搜索解决方案可以让我搜索给定的字符串,但允许雪花中的 2 个字符错误/缺失/空白?