ip有效性检测及代码优化
Posted gykai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ip有效性检测及代码优化相关的知识,希望对你有一定的参考价值。
说明:最近编写代码时,需要用C语言实现设置ip地址的功能,奈何本人所涉及的能力有限,通过网上查阅,找到了一个可以使用的程序代码,其中,有个检查ip地址是否有效的函数,但该函数却存在着一些不安全性,恰同时我刚好需要该函数,因此,我对该函数进行了一些优化,在此,想分享一下自己在优化该程序过程中的一些想法和思路。借此,希望能够和各位前辈进行交流。其中,原代码编写者的博客地址是:https://blog.csdn.net/lihuibo128/article/details/43668065 。
如果该代码还存在着不足,希望各位前辈能够批评指正。
一、源程序函数
包含的头文件:
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<string.h> #include<regex.h>
源程序:
/* 函数返回值: 0 :成功 -1 :失败 */ int check_right_ip(const char *ip) { int status = 0; int cflags = REG_EXTENDED; regmatch_t pmatch[1]; const size_t nmatch = 1; regex_t reg; char str_ip[30] = ""; const char *pattern = "[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}";//存在局限 strcpy(str_ip, ip); regcomp(®, pattern, cflags); status = regexec(®,str_ip,nmatch,pmatch,0); if(status==REG_NOMATCH) { printf("No match "); return -1; } else if(status == 0) { return 0; } regfree(®); return 0; }
说明:在源程序中,所使用的是利用正则表达式来进行数据位的有效检测,关于正则表达式函数的的用法,由于本篇主要侧重点在于代码的优化,在此,并不多详细讲解。可以参考网上其他博主的相关介绍。该程序的测试主程序如下:
int main() { char *ip = "192.168.1.12"; int res = 0; res = check_right_ip(ip); if (res == -1) { fprintf(stdout, "the format of ip is wrong... "); return -1; } fprintf(stdout, "the format of ip is right "); return 0; }
运行结果:
通过运行结果,可以看到,该程序运行正常。
二、程序的优化之数据有效性的检测
通过上述的简单测试,可以看到,该程序可以正常运行,但却存在着一些潜在的bug。首先,我们都知道,IP的有效格式是:"192.168.1.12",但比如有一天有人想输入的ip地址是:“192.168.1.12.12”,那么该程序的的运行结果是怎么的呢,如下是测试的主程序:
int main() { char *ip = "192.168.1.12.12"; int res = 0; res = check_right_ip(ip); if (res == -1) { fprintf(stdout, "the format of ip is wrong... "); return -1; } fprintf(stdout, "the format of ip is right "); return 0; }
编译运行之后的结果如下:
通过结果发现,该程序竟然运行正确,但这是我们想要的结果吗?结果是否定的,因此,我们需要考虑如果避免这种情况,通过对比两个ip地址我们可以发现,其中的点"."的个数是不一样的,因此,我们可以来计算该点的个数来判断一下ip地址的有效性。修改之后的check_right_ip()的函数如下:
/* 函数返回值: 0 :成功 -1 :失败 */ int check_right_ip(const char *ip) { int status = 0; int cflags = REG_EXTENDED; regmatch_t pmatch[1]; const size_t nmatch = 1; regex_t reg; char str_ip[30] = ""; const char *pattern = "[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}";//存在局限 /**************new add **********************/ char *pNext = NULL; char *pTmp = NULL; int count = 0; strcpy(str_ip, ip); regcomp(®, pattern, cflags); status = regexec(®, str_ip, nmatch, pmatch, 0); if(status == REG_NOMATCH) { printf("No match "); return -1; } regfree(®); pNext = (char *)ip;
while (1)
{
pTmp = strchr(pNext, ‘.‘);
if (pTmp == NULL)
{
if (count != 3)
{
return -1;
}
if (count == 3)
{
break;
}
}
count++;
pNext = pTmp + 1;
}
return 0; }
说明:在该函数中,我们增加了两个了指针,来进行数据位的有效计算“.”的个数,然后根据“.”的个数来判断其是否有效。下面是修改之后程序的运行结果
此时,可以看出,该程序的的运行结果与我们预期的结果一致,但这就结果这个问题了吗??考虑这么一种情况,假如有人小手一抖,只是在ip地址中,多增加了一个“.”,并没有在其后面添加数字,那么此时运行结果如下呢?下面我们来测试一下。主程序的代码如下:
int main() { char *ip = "192.168.1.12."; int res = 0; fprintf(stdout, "ip = %s ", ip); res = check_right_ip(ip); if (res == -1) { fprintf(stdout, "the format of ip is wrong... "); return -1; } fprintf(stdout, "the format of ip is right "); return 0; }
运行结果如下:
额,该程序能够运行出正确的结果。但本人在测试时,且发现,有时候并不能正确运行出结果,当时提示的错误信息是,段错误。通过排查发现,是 check_right_ip()中的pNext = pTmp + 1;这句话导致的,原因如下,当指针pTmp指向其最后一个"."时,pNexr = pTmp + 1;会指向其末尾, 再此使用strchr()函数时,就会导致段错误。此时,有两种方法解决,一种就是在 pNext = pTmp + 1; 之后,判断pNext是否等于‘ ’,另一种则是让pNext 最初指向 str_ip,而不是指向ip,因为str_ip数组中,末尾全部为‘ ‘,使用strchr()时,不会导致指向不该指向的地址。
修改之后的check_right_ip()的函数如下:
/* 函数返回值: 0 :成功 -1 :失败 */ int check_right_ip(const char *ip) { int status = 0; int cflags = REG_EXTENDED; regmatch_t pmatch[1]; const size_t nmatch = 1; regex_t reg; char str_ip[30] = ""; const char *pattern = "[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}";//存在局限 /**************new add **********************/ char *pNext = NULL; char *pTmp = NULL; int count = 0; strcpy(str_ip, ip); regcomp(®, pattern, cflags); status = regexec(®, str_ip, nmatch, pmatch, 0); if(status == REG_NOMATCH) { printf("No match "); return -1; } regfree(®); /**************new add **********************/ pNext = (char *)ip; while (1) { pTmp = strchr(pNext, ‘.‘); if (pTmp == NULL) { if (count != 3) { return -1; } if (count == 3) { break; } } count++; pNext = pTmp + 1; if (*pNext == ‘