精华内容
下载资源
问答
  • 判断IP地址是否合法 3. 判断MASK是否合法 4. 判断MASK和IP地址组合是否合法 测试: 测试环境:win7 VC++; 测试结果: 1、测试IP是否合法: 输入IP为0xFFFFFFFF即255.255.255.255,结果为不合法; 输入IP为0x...

    #include

    #include

    #ifdef WIN32

    #include

    #else

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #include

    #ifdef WIN32

    #pragma comment(lib,"wsock32.lib")

    #endif

    /*参数UINT32都为网络字节顺序。*/

    /*IP地址是否合法, 合法返回TURE,失败返回FALSE*/

    int netIpIsValid(_UINT32 IP)

    {

    int i;

    struct in_addr addr;

    addr.s_addr = IP;

    i = inet_addr(inet_ntoa(addr));

    if((i == 0)||(i == 0xffffffff))

    return FALSE;

    else

    return TRUE;

    }

    /*MASK子网掩码是否合法, 合法返回TURE,失败返回FALSE*/

    int netMaskIsValid(_UINT32 mask)

    {

    int i;

    unsigned long ii;

    i = netIpIsValid(mask);

    if(i==TRUE)

    {

    ii = ntohl(mask);

    if((ii|ii-1)==0xffffffff)

    {

    return TRUE;

    }

    }

    return FALSE;

    }

    /*MASK子网掩码是否合法, 合法返回TURE,失败返回FALSE*/

    int netMaskAndIpIsValid(_UINT32 IP, _UINT32 mask)

    {

    int i;

    int a, b=0, c;

    i = netIpIsValid(IP);

    if(i!=TRUE)

    return FALSE;

    i = netMaskIsValid(mask);

    if(i!=TRUE)

    return FALSE;

    a = IP&0x000000ff;

    b = ntohl(mask);

    /*首先与默认子网掩码比较*/

    if(a>0&&a<127)

    {

    if(mask<0x000000ff)

    return FALSE;

    if(mask>0x000000ff)

    b-=0xff000000;

    }

    if(a>=128&&a<=191)

    {

    if(mask<0x0000ffff)

    return FALSE;

    if(mask>0x0000ffff)

    b-=0xffff0000;

    }

    if(a>=192&&a<=223)

    {

    if(mask<0x00ffffff)

    return FALSE;

    if(mask>0x00ffffff)

    b-=0xffffff00;

    }

    /*每个子网段的第一个是网络地址,用来标志这个网络,最后一个是广播地址,用来代表这个网络上的所有主机.这两个IP地址被TCP/IP保留,不可分配给主机使用.*/

    c = ~ntohl(mask)&ntohl(IP);

    if(c==0||c==~ntohl(mask))

    return FALSE;

    /*RFC 1009中规定划分子网时,子网号不能全为0或1,会导致IP地址的二义性*/

    if(b>0)

    {

    c = b&(ntohl(IP));

    if(c==0||c==b)

    return FALSE;

    }

    return TRUE;

    }

    /*测试主网和子网是否匹配,也可测试两个主机IP是否在同一网段内*/

    int netIPAndSubnetValid(_UINT32 IP, _UINT32 subIP, _UINT32 mask)

    {

    int i;

    int addr1, addr2;

    i = netMaskAndIpIsValid(IP, mask);

    if(i!=TRUE)

    return FALSE;

    i = netMaskAndIpIsValid(subIP, mask);

    if(i!=TRUE)

    return FALSE;

    addr1 = IP&mask;

    addr2 = subIP&mask;

    if(addr1!=addr2)

    return FALSE;

    return TRUE;

    }

    技术实现及功能:

    1. 用C语言实现

    2. 判断IP地址是否合法

    3. 判断MASK是否合法

    4. 判断MASK和IP地址组合是否合法

    测试:

    测试环境:win7 VC++;

    测试结果:

    1、测试IP是否合法:

    输入IP为0xFFFFFFFF即255.255.255.255,结果为不合法;

    输入IP为0x00000000即0.0.0.0,结果为不合法;

    输入IP为0x00000000--0xFFFFFFFF即在0.0.0.0--255.255.255.255之间(全0和全1除外),结果为合法。

    2、测试子网掩码是否合法:

    输入0x00C0FFFF(1111 1111.1111 1111.1100 0000),结果合法;

    输入一个无符号int型数,二进制形式为 左边为全1右边为全0,结果合法,其余形式不合法。

    3、测试子网掩码和IP是否匹配:

    输入IP为0x410AA8C0即192.168.10.65(C类IP),输入子网掩码为0xC0FFFFFF,结果匹配,输入小于0x00FFFFFF的子网掩码时不匹配;

    输入IP为0x0141A885即133.168.65.1(B类IP),输入子网掩码为0x00C0FFFF,结果匹配,输入小于0x0000FFFF的子网掩码时不匹配;

    输入IP为0x0100413F即63.65.0.1(A类IP),输入子网掩码为0x0000C0FF,结果匹配,输入小于0x000000FF的子网掩码时不匹配。

    子网段内第一个和最后一个IP不可分配;子网号全0或全1的子网不可用,此时的结果都为不匹配。

    4、测试两个IP是否在同一子网段:

    输入两个IP为0x0C81C480 0x118FC480,输入子网掩码为0x00C0FFFF,结果为两个IP在同一网段;

    输入两个IP为0x0C81C480 0x117FC480,输入子网掩码为0x00C0FFFF,结果两个IP不在同一网段。

    备注:测试数据为无符号int型,网络字节顺序。

    补充知识:

    一般的,32位的IP地址分为两部分,即网络号和主机号,我们分别把他们叫做IP地址的“网间网部分”和“本地部分”。子网编址技术将本地部分进一步划分为“物理网络”部分和“主机”部分,其中“物理网络”用于标识同一IP网络地址下的不同物理网络,即是“子网”。

    A类IP段  0.0.0.0 到127.255.255.255

    B类IP段  128.0.0.0 到191.255.255.255

    C类IP段  192.0.0.0 到223.255.255.255

    XP默认分配的子网掩码每段只有255或0

    A类的默认子网掩码 255.0.0.0     一个子网最多可以容纳1677万多台电脑

    B类的默认子网掩码 255.255.0.0    一个子网最多可以容纳6万台电脑

    C类的默认子网掩码 255.255.255.0   一个子网最多可以容纳254台电脑

    以C类地址为例。IP地址中的前3个字节表示网络号,后一个字节既表明子网号,又说明主机号,还说明两个IP地址是否属于一个网段。如果属于同一网络区间,这两个地址间的信息交换就不通过路由器。如果不属同一网络区间,也就是子网号不同,两个地址的信息交换就要通过路由器进行。

    看一个例子:

    A的IP地址:11000000,10101000,00000000,00000101

    子网掩码:11111111,11111111,11111111,00000000

    B的IP地址:11000000,10101000,00000000,00010110

    看上边的内容,子网掩码在左边一共有24位为1,那这样的意思就是如果两个IP地址的前24位都相同的话,那这两个IP地址就是在同一个网段内,看到我红色标记的A和B的地址都相同,那这就说明A和B在同一个网段内。

    再看一个例子,如果还是A地址的数据发到C地址,C的IP地址为192.168.56.21

    A的IP地址:11000000,10101000,00000000,00000101

    子网掩码:11111111,11111111,11111111,00000000

    C的IP地址:11000000,10101000,00111000,00010101

    看上边的A和C,按照子网掩码的要求,如果C的前24位和A的前24位都相同的话,那么A和C才是同一网段的,看上边C的地址,我用蓝色来标注不同的位数,这样A 和C就不在同一个网段内,路由器就不能直接把A要发给C的数据直接经过一个路由器给发送过去,这样路由器就要先将A的数据转发到另外一个路由器(一个不行就继续往下发),然后再发到C上。

    ● 字节序转换函数

    htons 把 unsigned short 类型从主机序转换到网络序

    htonl 把 unsigned long 类型从主机序转换到网络序

    ntohs 把 unsigned short 类型从网络序转换到主机序

    ntohl 把 unsigned long 类型从网络序转换到主机序

    这几个函数很好记,比如htons中hton代表host to network, s代表unsigned short

    char FAR * inet_ntoa( struct in_addr in);

    将一个IP转换成一个互联网标准点分格式的字符串。

    in_addr_t inet_addr(const char *cp);

    将一个点分十进制的IP转换成一个长整数型数(u_long类型)。返回值已是网络字节顺序,可以直接作为internet 地址

    一个函数返回值为TRUE或FALSE 只有这两种返回值时 在判断返回值时不用 if(i==TRUE)或if(i==FALSE),而用if(i) if(!i)  编程规范。

    inet_ntoa()返回的字符串是临时装在一个静态分配的缓冲区里面,下一次调用此函数的时候缓冲区会被重写

    展开全文
  • 题目名称: IP地址合法性及子网判断程序 完成时间: 2020.03.02 - 2020.04.05 专业: 网络工程 班级: 192 学号: 2019083221 成绩: 需求分析: 根据任务要求,该系统可以实现IP地址合法性和子网的判断,相应...

    大连民族大学
    计算机科学与工程学院课程设计报告
    课程设计名称: 程序设计基础课程设计
    题目名称: IP地址合法性及子网判断程序
    完成时间: 2020.03.02 - 2020.04.05
    专业: 网络工程
    班级: 192
    学号: 2019083221
    成绩:

    需求分析
    根据任务要求,该系统可以实现IP地址合法性和子网的判断,相应的函数应该能够判断点分十进制+子网掩码和CIDR网络地址是否合法,并输出子网容量和子网掩码等相关的网络信息。还要能够对两个IPV4地址是否属于同一个子网进行判断。
    输入:程序提供菜单系统,用户根据相应的各级菜单进行选择,可以实现点分十进制+子网掩码的判断,CIDR网络地址的判断,两个IPV4地址是否属于同一个子网内。并经输入信息保存了文件中。
    输出/结果:从输出和信息中获得信息,并根据相应的函数输出相关的网络信息。
    概要设计:
    在这里插入图片描述

    详细设计:

    功能:保存31正确的子网掩码
    参数说明

    Char rightmask[31][16] = {"0.0.0.0","128.0.0.0","192.0.0.0","224.0.0.0","240.0.0.0","248.0.0.0","252.0.0.0","254.0.0.0","255.0.0.0""255.128.0.0","255.192.0.0","255.224.0.0","255.240.0","255.248.0.0","255.252.0.0","255.254.0.0","255.255.0.0","255.255.128.0","255.255.192.0","255.255.224.0","255.255.240.0","255.255.248.0","255.255.252.0","255.255.254.0","255.255.255.0","255.255.255.128","255.255.255.192","255.255.255.224","255.255.255.240","255.255.255.248","255.255.255.252" };
    

    ringmask[31][16]:全局数组,二维数组保存全部合法的子网掩码。

    功能:判断子网掩码是否合法
    参数说明:
    int Subnet_Mask_judge(char* subnet)
    Subnet:输入参数,数组类型指针,指向需要判断的子网掩码字符数组。
    返回值:判断正确返回1,判断错误返回1。
    算法:
    if(IP_address_judge(subnet) != 0)
    保证掩码必须是一个合法的IPv4地址
    if(strcmp(subnet,rightmask[i])==0)
    与rightmask比较是否有相同的,相同则掩码合法,反之不合法。

    功能:判断IPV4地址是否合法。
    参数说明:
    StrIp:输入参数,数组类型指针,指向需要判断的ip字符数组。
    返回值:-1或0。
    算法:

    功能:判断CIDR地址是否合法。
    参数说明:
    CIDR_judge(char CIDR)
    CIDR:输入参数,字符串类型指针,指向需要输入的CIDR字符串。
    返回值:判断正确返回0,错误返回-1。
    算法:
    for(i=0; CIDR[i]!=’/’; i++) //判断条件为不等于’/’
    {
    strCIDR[i]=CIDR[i];
    }
    截取存储CIDR前面的ip地址
    i++; // 跳过’/’
    for(; CIDR[i]!=’\0’; i++) //保存 前缀
    {
    sum=10
    sum +CIDR[i]-‘0’;
    }
    截取存储CIDR的前缀
    if(IP_address_judge(strCIDR) ==0)
    if(sum >=0 &&sum <= 32 )
    判断ip和前缀是否合法

    功能:将掩码转化为前缀形式。
    参数说明:
    Mask_Prefix_change(char* mask)
    Mask:输入参数,用来存储需要转换的掩码。
    返回值:返回前缀的值。
    算法:
    for (i = 0; i<31; ++i)
    控制循环在rightmask中检索。
    if (strcmp(mask, rightmask[i]) == 0)
    return i;i的值就是前缀长度。

    功能:前缀转化为掩码
    参数说明:
    Prefix_Mask_change(int n)
    n:输入参数,用来传递前缀的值。
    返回值:返回掩码的值。
    算法:
    if (n >= 0 && n <= 31)
    return rightmask[n];
    else
    return “Error Prefix”;

    功能:计算子网容量
    参数说明:
    Mask_capacity (int n)
    n: 输入参数,用来传递前缀的值。
    返回值:子网容量的大小,应该减去网络地址和广播地址。
    算法:
    for(i=0;i<(31-n);i++)
    {
    sum *=2;
    }
    sum = sum - 2;

    功能:根据输入的IP地址和掩码MASK求子网地址
    参数说明:
    char* Subnet_one(char *IP,char *MASK)
    IP:输入参数,用来传递的点分十进制ip地址的值。
    MASK:输入参数,用来传递子网掩码的值。
    返回值:子网地址的值。
    算法:
    sscanf(IP, “%u.%u.%u.%u”, &IP_n[3], &IP_n[2], &IP_n[1], &IP_n[0]);
    sscanf(MASK, “%u.%u.%u.%u”, &MASK_n[3], &MASK_n[2], &MASK_n[1], &MASK_n[0]);
    sprintf(SUBNET, “%u.%u.%u.%u”, IP_n[3] & MASK_n[3], IP_n[2] & MASK_n[2], IP_n[1] & MASK_n[1], IP_n[0] & MASK_n[0]);
    主要利用sscanf函数和sprintf函数读取和储存形如255.255.255.255格式的子网字符串,并输出。

    功能:判断并保存点分十进制+子网掩码
    参数说明:
    Input_ip:字符型数组,用来保存输入的ip地址。
    Input_subnet:字符型数组,用来保存输入的子网掩码地址。
    返回值:无。
    算法:
    FILE *fp= fopen(“ip.txt”, “w”); 创建一个ip.txt文件,权限为写。
    fp = fopen(“ip.txt”, “w”)) == NULL;利用if语句判断文件是否正常打开正常打开继续程序,反之报错。
    IP_address_judge(Input_ip) == 0; 判断IP地址是否合法,合法程序继续运行,反之利用while语句重新输入IP地址。
    fprintf(fp,"%s",Input_ip);将IP地址存储到文件中。
    Subnet_Mask_judge(Input_subnet) == 1;
    fprintf(fp," %s\n",Input_subnet);与IP地址方法同理。

    功能:判断并保存CIDR。
    参数说明:
    Input_CIDR:字符型变量,用来保存输入的CIDR地址。
    返回值:无。
    算法:
    fpp = fopen(“CIDR.txt”, “w”)) == NULL;打开CIDR.txt文件并利用if语句判断文件是否正常打开。正常打开文件,反之报错。
    CIDR_judge(Input_CIDR) ==0;
    fprintf(fpp,"%s\n",Input_CIDR);判断CIDR格式是否正确,如果正确就写入到文件中,反之就利用while循环重新输入CIDR地址。

    功能:输出点分十进制+子网掩码相关信息。
    参数说明:
    get_ip[16]:字符型数组,用来在文件中读出ip地址。
    get_subnet[16]:字符型数组,用来在文件中读取子网掩码。
    Mask_address[16] :字符型数组,用来保存自定义函数中返回的子网掩码地址。
    Prefix:整型变量,用来储存子网转换的前缀长度。
    返回值:无。
    算法:
    FILE *fp= fopen(“ip.txt”, “r”); 打开文件,并给予读权限。
    fscanf(fp,"%s %s",get_ip,get_subnet);读取ip和掩码的值。
    prefix = Mask_Prefix_change(get_subnet);将掩码转化为前缀长度
    Mask_capacity (prefix);利用转化的前缀长度,计算子网容量。
    Subnet_one(get_ip,get_subnet);计算子网地址。

    功能:输出CIDR的相关信息。
    参数说明:
    get_CIDR[20] :字符型数组,用来在文件中读取CIDR地址。
    get_CIDR_up [16] :字符型数组,用来保存CIDR中的ip地址。
    get_CIDR_down = 0:无符号整形变量,用来保存前缀大小。
    IP_m[4]:无符号字符变量,用来保存ip地址的四段数字。
    返回值:无。
    算法:
    FILE *fpp= fopen(“CIDR.txt”, “r”);打开文件,并给予读权限
    fscanf(fpp,"%s",get_CIDR);读取文件CIDR地址。
    sscanf(get_CIDR,"%u.%u.%u.%u/%u",&IP_m[0],&IP_m[1],&IP_m[2],&IP_m[3],&get_CIDR_down); 将CIDR地址分段保存。
    sprintf(get_CIDR_up,"%u.%u.%u.%u",&IP_m[0],&IP_m[1],&IP_m[2],&IP_m[3]);
    把分段保存的CIDR地址中一部分组成ip地址。然后和点分十进制+子网掩码的方法一样,利用自定义函数计算子网容量和子网地址。

    功能:两个ip地址是否属于同一个子网输出。
    参数说明:
    ip[2][16]:字符型数组,用来保存键盘输入的两个ip地址。
    mask[2][16]:字符型数组,用来保存键盘输入的两个子网掩码。
    tool[2][16]::字符型数组,用来接受函数的返回值。
    返回值:无。
    参数说明:
    IP_address_judge(ip[0]) = 0 && IP_address_judge(ip[1]) = 0
    Subnet_Mask_judge(mask[0]) =1&&Subnet_Mask_judge(mask[1]) = 1
    strcpy(tool[0],Subnet_one(ip[0],mask[0]));
    strcpy(tool[1],Subnet_one(ip[1],mask[1]));
    首先判断ip地址是否合法,不合法重新输入,如果合法,判断子网掩码是否合法同理。

    使用说明:
    在这里插入图片描述
    打开程序后,弹出选择菜单栏。
    在这里插入图片描述
    需要继续输入ip地址,ip地址正确后继续输入子网掩码,均输入正确后给出子网容量和子网地址,并继续弹出菜单。
    在这里插入图片描述
    如果ip地址输入错误,会对相关信息报错,并重新输入。
    在这里插入图片描述
    如果子网掩码输入错误,会对相关信息报错,并重新输入。
    在这里插入图片描述
    需要继续输入CIDR地址,CIDR地址正确后继续输入子网掩码,均输入正确后给出子网容量和子网地址,并继续弹出菜单。
    在这里插入图片描述
    对错误的CIDR进行的判断并重新输入。
    在这里插入图片描述
    选择选项3,需要按步骤输入第一个ip地址,第二个地址。再输入两个子网掩码进行判断是否属于同一个子网。
    在这里插入图片描述
    如果输入错误也会对相关错误进行报错,并重新输入。
    在这里插入图片描述
    选项4,退出程序。
    在这里插入图片描述
    心得体会:
    长达三周的课程设计终于告一段落,在这个活动中我真的收获了很多的知识,提升了自己的能力。说实话,长达两个月的寒假,没有复习c语言,真的忘记了很多很多的知识,连最基本的do-while语句都忘记了,但是我没有被困难打到。第一周我没有进行代码的编写,我选择的是第二题“ip地址合法性和子网掩码判断”,这需要对IPV4地址和CIDR地址相关的知识有了解,因此在第一周我选择去复习c语言的知识,并在B站上面学习了IPV4地址和CIDR地址的相关信息。第二周开始着手对代码进行编写,一开始对IPV4地址合法性进行判断的函数遇到了很大障碍,总是对错误有遗漏,要不就是对相关的判断冲突。后来,我冷静下来对IPV4的错误六大错误进行整理,梳理它们的内在联系。最终以“.”这个字符为标志进行判断解决问题。从中我懂得了,我们遇到问题一定不能着急,心平气和的去梳理内在联系,寻求解决问题的方法。第三周开始我开始优化的代码,如一个二维数组在三个自定义的文件中都需要使用就把它定义为一个全局变量,成功的简化代码,避免数据的重复写入。还优化了主函数从130多行变成了30行,从中我懂得,主函数不要写过多的东西一简洁明了为主,这样的话主函数相当于一个目录,大大提高了程序的可读性。我在优化的过程中,还使用了对文件的操作,fopen()、fclose()、fprintf()、fscanf()、fgetc()、fput()等。还有文件的权限‘r’、‘w’、‘a’等。在我使用文件操作的时候,出现了一个问题,文件写入后显示写入成功,但是读取的信息完全错误,打开相应的txt文件发现文件里没有信息。找了一整个上午都没有发现错误,只能求助老师,在王德高老师的帮助下,发现是一个文件读取函数中的读权限给成了写权限,导致的错误,因为自己的不细心浪费了很长时间,在编写代码的时候一定要细心有时候敲错一个字母,程序都可能无法正常运行。
    课程设计为我们提供了一个把理论进行实践的绝好机会,课程设计要求我们既动手又动脑,断粮我们的分析实际问题,解决实际问题的能力,同时也提高我们适应实际,实践的能力。
    最后,在这里感谢第二题的指导教师王德高老师,在群里给我们讲解ip的相关知识,解答学生问题的时候,特别的耐心,感谢王德高老师。

    附录:课程设计源代码。
    #include <stdio.h>
    #include <string.h>
    char CIDR_up[20] = {0};
    int  CIDR_down;
    
    char rightmask[31][16] = {"0.0.0.0","128.0.0.0","192.0.0.0","224.0.0.0","240.0.0.0","248.0.0.0","252.0.0.0","254.0.0.0","255.0.0.0",
    	                          "255.128.0.0","255.192.0.0","255.224.0.0","255.240.0","255.248.0.0","255.252.0.0","255.254.0.0","255.255.0.0",
    	                          "255.255.128.0","255.255.192.0","255.255.224.0","255.255.240.0","255.255.248.0","255.255.252.0","255.255.254.0","255.255.255.0",
    	                          "255.255.255.128","255.255.255.192","255.255.255.224","255.255.255.240","255.255.255.248","255.255.255.252"
    	                         };
    
    //判断IPv4地址是否合法
    int IP_address_judge(char *strIp)
    {
    	
    	int num = 0, numcount=0;      // num为每段的十进制数,numcount为每段的位数
    	int dotNum = 0;		         //dotNum为'.'的个数
    	do
    	{
    		if((*strIp == '0') )   //字段中的数字小于10,且不能以0开头
    		{ 
    				if(*(strIp+1) != '.'&&*(strIp+1) != '\0')
    				{	
    				   if(*(strIp-1) == '.')
    				   {   
    						printf("当字段中的数字小于10,不能以0开头\n");
    					    return -1;
    					}
    					
    				}
    			}
    		if(*strIp >= '0' && *strIp <= '9')
    		{
    				num = 10 * num + *strIp - '0';
    				numcount++;
    				if (numcount>=4) //每段位数 numcount 最大为3位
    				{ 
    					printf("IPv4地址的每一段最大为3位数,您输入了 %d 位数\n",numcount);
    					return -1;
    				}
    				
    			} 
    		else if(( *strIp == '.') || (*strIp) == '\0' ) 
    		{
    			//如果包含'..' 或 以 '.'结尾
    			if( *(strIp - 1) == '.' || (*(strIp-1)) == '\0' ) 
    			{
    				printf("IPv4地址不能包含'..' 或 以 '.'开头或结尾\n");
    				return -1;
    			}
    			//每段的数字num> 255 或 num< 0
    			if(num < 0 || num > 255)
    			{
    				printf("IPv4地址每段的数值必须在0~255之间\n");
    				return -1;
    				}
    			num = 0;
    			if(*strIp == '.') // 若是正常的 '.'
    			{	
    				dotNum++;	 	//记录正常的'.'的个数
    				numcount=0;		//每段的位数计数器 numcount 归零
    			}
    		}
    		 else //包含非法字符
    		{	
    			printf("IPv4地址包含非法字符\n");
    			return -1;
    		 	}
    	 } while(*(strIp++));
    
    	if( dotNum == 3 ) 
    	{
    		// 输入正确
    		return 0;
    		}
    	else 
    	{
    		//'.'的个位不为3
    		printf("IPv4地址中的'.'不为3\n");
    		return -1;
    		}
    	
     }
    
    //判断子网掩码是否合法
    int Subnet_Mask_judge(char* subnet)
    {
    
    	if(IP_address_judge(subnet) != 0) //掩码必须是一个合法的IPv4地址
    	{	
    		return 0;
    	}
        int i = 0; 
    	for(i=0; i<31; i++ ) 
    	{
    		if(strcmp(subnet,rightmask[i])==0) 
    		{
    			return 1;
    		}
    	}
    
    	return 0;
    }
    
    //CDIR是否合法判断
    int CIDR_judge(char *CIDR)
    {   
       int i,sum = 0;
      char strCIDR[16];
      if(strstr(CIDR,"/") == NULL) 
      {
      	printf("CIDR地址输入不正确!\n");
      	return -1;
      }
      for(i=0; CIDR[i]!='/'; i++)	//判断条件为不等于'/' 保留前面的ip 
    	{
    		strCIDR[i]=CIDR[i];
    	}
    	i++;	// 跳过'/' 
    	for(; CIDR[i]!='\0'; i++)  //保存 前缀 
    	{
    		sum=10*sum +CIDR[i]-'0';
    	}
    	 if(IP_address_judge(strCIDR) ==0)
    	 {
    	 	if(sum >=0 &&sum <= 32 )
    	 	{
    	 		strcpy(CIDR_up,strCIDR);
    	 		CIDR_down = sum;
    	 		return 0;
    		 }
    		 else
    		 {
    		 	printf("CIDR中的前缀非法!\n"); 
    		 	return -1; 
    		 }
    	 }
         else
         {
         	printf("CDIR中的IP地址非法!\n");
    		 return -1; 
    	 }
    	
    }
    
    //将掩码转化为前缀形式 
    int Mask_Prefix_change(char* mask) 
      {
      	int i = 0;
    	
    	for (i = 0; i<31; ++i) 
    	{
    		if (strcmp(mask, rightmask[i]) == 0) 
    		{
    			return i;	//rightmask[i]的下标i就是前缀长度
    		}
    	}
    	return -1;
    }
    
    //前缀转化为掩码 
    char* Prefix_Mask_change(int n)
    {
    
    	if (n >= 0 && n <= 31) 
    	{
    		return rightmask[n];	//rightmask[n]就是掩码
    	}
    	else
    	{
    		return "Error Prefix";
    	}
    
     }
    
    //子网容量运算
    int Mask_capacity (int n)
    {
    	int sum = 2;
    	int i = 0; 
    	for(i=0;i<(31-n);i++)
    	{
    		sum *=2;
    	 } 
    	 sum = sum - 2;
    	return sum;
     }
    
    //根据输入的IP地址和掩码MASK求子网地址
     char* Subnet_one(char *IP,char *MASK) 
    {
    	unsigned int IP_n[4],MASK_n[4]; //IP_n, MASK_n分别是IP地址和掩码MASK的各段数字
    	sscanf(IP, "%u.%u.%u.%u", &IP_n[3], &IP_n[2], &IP_n[1], &IP_n[0]);
    	sscanf(MASK, "%u.%u.%u.%u", &MASK_n[3], &MASK_n[2], &MASK_n[1], &MASK_n[0]);
    
    	char SUBNET[16] = "";
    	sprintf(SUBNET, "%u.%u.%u.%u", IP_n[3] & MASK_n[3], IP_n[2] & MASK_n[2], IP_n[1] & MASK_n[1], IP_n[0] & MASK_n[0]);
    
    	return SUBNET;
      }
      
    //判断并保存点分十进制+子网掩码 
    void write_ip()
    {
    FILE *fp= fopen("ip.txt", "w");//定义文件指针 
    char Input_ip[16]="";
    char Input_subnet[16]=""; 
    if((fp = fopen("ip.txt", "w")) == NULL)
           {
           	printf("can't open the file! \n");
    		} 
    else
    	{
    		while(1)
    		{
    			printf("请输入IPV4地址:");
    			scanf("%s",Input_ip);
    			if(IP_address_judge(Input_ip) == 0) 
    			{
    				fprintf(fp,"%s",Input_ip);
    				while(1)
    				{
    					printf("请输入子网掩码:");
    					scanf("%s", Input_subnet);
    					if(Subnet_Mask_judge(Input_subnet) == 1)
    					{
    					 	fprintf(fp,"    %s\n",Input_subnet);
    					 	printf("IPv4地址和掩码输入正确\n");
    						break;
    					}
    					else
    					{
    						printf("子网掩码输入错误。\n");
    					}
    				
    				}	
    			break;
    			} 
    			else 
    			{
    				//printf("IPv4地址输入错误!\n");
    			}
    		}
    	}
    	
    	fclose(fp); 	
     } 
     
     //判断并保存CIDR 
    void write_CIDR()
    {
    	FILE *fpp= fopen("CIDR.txt", "w");
    	char Input_CIDR[20]="";
    	if((fpp = fopen("CIDR.txt", "w")) == NULL)
            printf("can't open the file! \n");
    	else
    	{
    		while(1) 
    	{
    		printf("请输入CIDR地址:");
    		scanf("%s", Input_CIDR);
    		if( CIDR_judge(Input_CIDR) ==0) 
    		{
    			printf("CIDR地址输入正确\n");
    			fprintf(fpp,"%s\n",Input_CIDR);
    			break;
    			}
    		else
    		{
    			//printf("CIDR地址输入不正确!\n");
    			} 
    			
    		}
    	}
    	
    	fclose(fpp);
    }
    //输出点分十进制+子网掩码相关信息 
    void read_ip()
    {
     FILE *fp= fopen("ip.txt", "r");//定义文件指针 
     char get_ip[16]="";
     char get_subnet[16]="";
     char Mask_address[16] = {0}; //储存子网地址  
     int prefix = 0;
     if((fp = fopen("ip.txt", "r")) == NULL)
           {
           	printf("can't open the file! \n");
    		} 
     else
    	{
    		fscanf(fp,"%s    %s",get_ip,get_subnet);	
            prefix = Mask_Prefix_change(get_subnet);
    		printf("子网容量为:%d\n",Mask_capacity (prefix));
    		strcpy(Mask_address,Subnet_one(get_ip,get_subnet)) ;
    		printf("子网网络地址为:%s\n",Mask_address);
    	}
    	fclose(fp);
    }
    
    //输出CIDR的相关信息 
    void read_CIDR()
    {
    	FILE *fpp= fopen("CIDR.txt", "r");
    	char get_CIDR[20] = "";
    	char get_CIDR_up [16] = "";
    	unsigned int get_CIDR_down = 0,IP_m[4];
    	char return1[16] = "";  //用来接收函数返回值
    	char return2[16] = ""; 
    	if((fpp = fopen("CIDR.txt", "r")) == NULL)
           {
           	printf("can't open the file! \n");
    		} 
     	else
    	{
    	fscanf(fpp,"%s",get_CIDR);
    	sscanf(get_CIDR,"%u.%u.%u.%u/%u",&IP_m[0],&IP_m[1],&IP_m[2],&IP_m[3],&get_CIDR_down);
    	sprintf(get_CIDR_up,"%u.%u.%u.%u",&IP_m[0],&IP_m[1],&IP_m[2],&IP_m[3]);
    	printf("子网容量为:%d\n",Mask_capacity (get_CIDR_down));
    	strcpy(return2,Prefix_Mask_change(get_CIDR_down));
    	strcpy(return1,Subnet_one(CIDR_up,return2));
    	printf("子网地址为:%s\n",return1);	
    	}
    	fclose(fpp);
    }
    
    //两个ip地址是否属于同一个子网输出
    void IP_two_main() 
    {
    	char ip[2][16] = {""}, mask[2][16] = {""}, tool[2][16]={""}; //用来接收函数返回值 
    		while(1)
    		{
    			printf("请输入第一个IPV4地址:");
    		  	scanf("%s",ip[0]); 
    			printf("请输入第二个IPV4地址:");
    			scanf("%s",ip[1]);
    			if(IP_address_judge(ip[0]) == 0 && IP_address_judge(ip[1]) == 0)
    			{
    				printf("请输入第一个IPV4地址的子网掩码:");
    				scanf("%s",mask[0]);
    			
    				printf("请输入第二个IPV4地址的子网掩码:");
    				scanf("%s",mask[1]);
    				if(Subnet_Mask_judge(mask[0]) ==1&&Subnet_Mask_judge(mask[1]) == 1)
    				{
    					strcpy(tool[0],Subnet_one(ip[0],mask[0]));
    					strcpy(tool[1],Subnet_one(ip[1],mask[1]));
    					if(strcmp(tool[0],tool[1]) == 0)
    					{
    					  printf("两个IPV4地址属于同一子网\n"); 
    					  break; 
    					}
    					else
    					{
    					  printf("两个IPV4地址不属于同一子网\n"); 
    					  break;	
    					}
    				}
    				else
    				{
    					printf("子网输入错误,请重新输入。\n");
    				 } 
    			}
    			else
    			{
    				printf("ip地址输入错误,请从新输入。\n");
    			}
    		}
    			
     } 
    int main() 
    {
    	while(1)
    	{
    			int i=0;
    			printf("**********************************************************\n");
    			printf("	1.点分十进制+子网掩码判断\n");
    			printf("	2.CDIR型ip地址判断\n");
    			printf("	3.判断两个ip地址是否属于一个子网\n");
    			printf("	4.退出程序\n");
    			printf("***********************************************************\n");
    			printf("请选择您需要的服务:");
    			scanf("%d",&i);
    			switch(i)
    			{
    				case 1:
    					write_ip();
    					read_ip();
    			    	break;
    				case 2:
    			    	write_CIDR();
    			    	read_CIDR();
    			    	break;
    				case 3:
    			    	IP_two_main();    
    			    	break;
    				case 4: 
    			    	printf("欢迎下次使用本程序。\n");
    			    	goto over;
    				default:
    					printf("您输入的选项非法!\n");
    					break;
    		 		} 
    		} 
    over:		
    	return 0;
    }	
    
    
    展开全文
  • 1、c语言地址合法判断 bool IsIPaddress_standard(const char* pszIPAddr) { if (!pszIPAddr) return false; //若pszIPAddr为空 char IP1[100],cIP[4]; int len = strlen(pszIPAddr); int i = 0,j=len-1...

    1、c语言地址合法判断

    bool IsIPaddress_standard(const char* pszIPAddr)
    {
        if (!pszIPAddr) return false; //若pszIPAddr为空  
        char IP1[100],cIP[4];  
        int len = strlen(pszIPAddr);  
        int i = 0,j=len-1;  
        int k, m = 0,n=0,num=0;  
        //去除首尾空格(取出从i-1到j+1之间的字符):  
        while (pszIPAddr[i++] == ' ');  
        while (pszIPAddr[j--] == ' ');  
    
        for (k = i-1; k <= j+1; k++)  
        {  
            IP1[m++] = *(pszIPAddr + k);  
        }       
        IP1[m] = '\0';  
        char *p = IP1;  
        while (*p!= '\0')  
        {  
    
            if (*p == ' ' || *p<'0' || *p>'9') return false;  
            cIP[n++] = *p; //保存每个子段的第一个字符,用于之后判断该子段是否为0开头  
            int sum = 0;  //sum为每一子段的数值,应在0到255之间  
            while (*p != '.'&&*p != '\0')  
            {  
              if (*p == ' ' || *p<'0' || *p>'9') return false;  
              sum = sum * 10 + *p-48;  //每一子段字符串转化为整数  
              p++;  
            }  
            if (*p == '.') {  
                if ((*(p - 1) >= '0'&&*(p - 1) <= '9') && (*(p + 1) >= '0'&&*(p + 1) <= '9'))//判断"."前后是否有数字,若无,则为无效IP,如“1.1.127.”  
                   num++;  //记录“.”出现的次数,不能大于3  
    
                else  
                  return false;  
    
            };  
    
            if ((sum > 255) || (sum > 0 && cIP[0] =='0')||num>3) return false;//若子段的值>255或为0开头的非0子段或“.”的数目>3,则为无效IP  
    
      
    
            if (*p != '\0') p++;  
    
            n = 0;  
    
        }  
    
        if (num != 3) return false;  
    
        return true;
    }

    2、首尾去除空格

    void trim(const char* strin,char* strout)
    {
    	int i=0,m=0,len_ip=0,j=0,k=0;
    	
    	while(strin[k++]==' ')
    	{
    		if(k==strlen(strin))
    		{
    			memset(strout,0,sizeof(strout));
    			stpcpy(strout,"");
    			return;
    		}
    	}
    		
    	len_ip=strlen(strin);
    	j=len_ip-1;
    	while(strin[i++]==' ');
    	while(strin[j--]==' ');
    	strncpy(strout,strin+(i-1),(j+1)-(i-1)+1);
    	strout[j+1]='\0';
    }

     

    展开全文
  • C语言实现IP合法性判断

    千次阅读 2019-08-25 11:44:07
    #include<stdio.h> #include<string.h> int main() { char str[30]; int a,b,c,d,i;... printf("输入IP地址:\n"); while(scanf("%s",str)==1) { if(str[0]=='0' && str[1]!='.') ...
    #include<stdio.h>
    #include<string.h>
    int main()
    {
    	char str[30];
    	int a,b,c,d,i;
    	int flag=0;
    	printf("输入IP地址:\n");
    
    	while(scanf("%s",str)==1)
    	{
    		if(str[0]=='0' && str[1]!='.')
    			flag=1;
    		
    		for(i=0;i < (strlen(str)-2);i++)
    		{
    			if(str[i]=='.' && str[i+1]=='0' && str[i+2]!='.' && str[i+2]!='\0')
    				flag=1;
    		}
    			
    		if(sscanf(str,"%d.%d.%d.%d",&a,&b,&c,&d)==4 && a>=0 && a<=255 && b>=0 && b<=255 && c>=0 && c<=255 && d>=0 && d<=255 && flag==0)
    			printf("Yes\n");
    		
    		else
    			printf("No\n");
    	}
    	return 0;
    }
    
    展开全文
  • 判断IP地址,MAC地址合法性-C语言

    千次阅读 2015-08-14 16:19:25
    int isValidMac(char *value) { int r; //r=0:valid, else not valid char *reg="^[0-9A-F]\\([0-9A-F]\\:[0-9A-F]\\)\\{5\\}[0-9A-F]$"; r=ereg(reg,value); return r; } ...int isValidIp(char *value)
  • 一 原理1.IP合法关于IP地址合法性验证很简单,方法也很多,比如字符串分解、正则表达式等。2.子网掩码是否合法简单来讲,子网掩码就类似这样一串数字,前面一段是连续的1,类似“111111111“,后面一段是连续的0,...
  • 工作中经常碰到IP及子网掩码是否合法的判断,虽然可以google出答案,还是整理下记录下来,以后用时方便。...关于IP地址合法性验证很简单,方法也很多,比如字符串分解、正则表达式等。 2. 子网掩码是
  • 判断IP地址合法性, 1.不能出现除数字和点字符以外的的其他字符 2.数字必须在0-255之间,要注意边界。 题目分析: 因为一个IP是又四个数字组成,且可能存在符号和其他字符,故不能用整型数组处理,应该用字符...
  • 用sscanf判断ip地址的正确

    千次阅读 2009-07-11 12:52:00
    由于看到那个遍历字符串去逐个判断的...所以写了个小函数 #include #include /*该函数能够验证合法ip地址ip地址中可以有前导0,也可以有空格*/int isValidStr(char *buf,int *pAddr){ int part1,part2,part3,part
  • 你必须知道的495个C语言问题

    千次下载 热门讨论 2015-05-08 11:09:25
    这为什么是合法C语言表达式呢? 数组的指针 6.12 既然数组引用会退化为指针,如果array是数组,那么array和&array又有什么区别呢? 6.13 如何声明一个数组的指针? 动态数组分配 6.14 如何在运行时设定...
  • 《你必须知道的495个C语言问题》

    热门讨论 2010-03-20 16:41:18
    1.30 如何判断哪些标识符可以使用,哪些被保留了? 15 初始化 18 1.31 对于没有显式初始化的变量的初始值可以作怎样的假定?如果一个全局变量初始值为“零”,它可否作为空指针或浮点零? 18  1.32 下面的...
  • 1.30 如何判断哪些标识符可以使用,哪些被保留了? 15 初始化 18 1.31 对于没有显式初始化的变量的初始值可以作怎样的假定?如果一个全局变量初始值为“零”,它可否作为空指针或浮点零? 18  1.32 下面的...
  • 这为什么是合法C语言表达式呢?  数组的指针  6.12 既然数组引用会退化为指针,如果array是数组,那么array和&array;又有什么区别呢?  6.13 如何声明一个数组的指针?  动态数组分配  6.14 如何在运行时...
  • [你必须知道的495个C语言问题] 第1章 声明和初始化 基本类型 1.1 我该如何决定...这为什么是合法C语言表达式呢? 数组的指针 6.12 既然数组引用会退化为指针,如果array是数组,那么array和&array;又有什么区别...
  • 本书以问答的形式组织内容,讨论了学习或使用C语言的过程中经常遇到的一些问题。书中列出了C用户经常问的400多个经典问题,涵盖了初始化、数组、指针、字符串、内存分配、库函数、C预处理器等各个方面的主题,并分别...
  • 本书以问答的形式组织内容,讨论了学习或使用C语言的过程中经常遇到的一些问题。书中列出了C用户经常问的400多个经典问题,涵盖了初始化、数组、指针、字符串、内存分配、库函数、C预处理器等各个方面的主题,并分别...
  • 在线笔试的一道题

    2018-03-20 20:24:53
    题目有2大类,30道选择2道简答题(编程题),选择题涵盖PHP,数据库,数据结构(二叉树及遍历)操作系统,计算机网络,c语言等,简答题是判断ip地址合法性和判断一个数是否为三七数(只有3和7两个因子)。...
  • 入门学习Linux常用必会60个命令实例详解doc/txt

    千次下载 热门讨论 2011-06-09 00:08:45
    ◆ 网络操作命令:ifconfig、ip、ping、netstat、telnet、ftp、route、rlogin、rcp、finger、mail、 nslookup; ◆ 系统安全相关命令:passwd、su、umask、chgrp、chmod、chown、chattr、sudo ps、who; ◆ 其它...
  • 会计理论考试题

    2012-03-07 21:04:40
    判断题 1.计算机的常用输入设备有键盘和鼠标器。( Y ) 2.软盘要远离如电话、录音设备等热源、磁源。( Y ) 3.硬盘格式化分二个阶段,低级格式化和高级格式化。( N ) 4.硬盘格式化分三个阶段,其先后顺序为低级...
  • Java开发技术大全(500个源代码).

    热门讨论 2012-12-02 19:55:48
    HelloNative.h 用javah生成的C语言用的头文件 HelloNative.java 准备调用C函数的java文件 HelloNative.lib 用VC编译生成的静态库文件 HelloNative.obj 用VB编译生成的目标文件 HelloNativeTest.java 测试本地化...
  • 根据Netcraft在1999年10月的报告,有931122个域和321128个IP地址利用PHP技术。 1.2 PHP的先进之处 应用PHP有许多好处。当然已知的不利之处在于PHP由于是开放源码项目,没有什么商业支持,并且由此而带来的执行速度...

空空如也

空空如也

1 2
收藏数 26
精华内容 10
关键字:

c语言判断ip地址合法性

c语言 订阅