IP地址匹配

问题描述: 
在路由器中,一般来说转发模块采用最大前缀匹配原则进行目的端口查找,具体如下:

IP地址和子网地址匹配:

IP地址和子网地址所带掩码做AND运算后,得到的值与子网地址相同,则该IP地址与该子网匹配。

比如:

IP地址:192.168.1.100

子网:192.168.1.0/255.255.255.0,其中192.168.1.0是子网地址,255.255.255.0是子网掩码。

192.168.1.100&255.255.255.0 = 192.168.1.0,则该IP和子网192.168.1.0匹配

IP地址:192.168.1.100

子网:192.168.1.128/255.255.255.192

192.168.1.100&255.255.255.192 = 192.168.1.64,则该IP和子网192.168.1.128不匹配

最大前缀匹配:

任何一个IPv4地址都可以看作一个32bit的二进制数,比如192.168.1.100可以表示为:11000000.10101000.00000001.01100100,

192.168.1.0可以表示为11000000.10101000.00000001.00000000

最大前缀匹配要求IP地址同子网地址匹配的基础上,二进制位从左到右完全匹配的位数尽量多(从左到右子网地址最长)。比如:

IP地址192.168.1.100,同时匹配子网192.168.1.0/255.255.255.0和子网192.168.1.64/255.255.255.192,

但对于子网192.168.1.64/255.255.255.192,匹配位数达到26位,多于子网192.168.1.0/255.255.255.0的24位,

因此192.168.1.100最大前缀匹配子网是192.168.1.64/255.255.255.192。

请编程实现上述最大前缀匹配算法。

要求实现函数: 
void max_prefix_match(const char *ip_addr, const char *net_addr_array[], int *n)

【输入】ip_addr:IP地址字符串,严格保证是合法IPv4地址形式的字符串

net_addr_array:子网地址列表,每一个字符串代表一个子网,包括子网地址和掩码,

表现形式如上述,子网地址和子网掩码用’/’分开,严格保证是

合法形式的字符串;如果读到空字符串,表示子网地址列表结束

【输出】n:最大前缀匹配子网在*net_addr_array[]数组中对应的下标值。如果没有匹配返回-1

示例 
输入:

ip_addr = "192.168.1.100"

net_addr_array[] =

{

"192.168.1.128/255.255.255.192",

"192.168.1.0/255.255.255.0",

"192.168.1.64/255.255.255.192",

"0.0.0.0/0.0.0.0",

""

}

输出:n = 2

这题真麻烦,搞了好久~分高就是难

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 void max_prefix_match(const char *ip_addr, const char *net_addr_array[], int *n)
  5 {
  6     int i,j,ip[4],mask[4],l,len,net[4],sum;
  7     const char *p;
  8     i = 0;
  9     l = 0;
 10     sum = 0;
 11     len = 0;
 12     *n = -1;
 13     p = ip_addr;
 14     while (*p != ‘\0‘)
 15         {
 16             j = 0;
 17             while (*p >= ‘0‘ && *p <= ‘9‘)
 18             {
 19                 int k = *p - ‘0‘;
 20                 j = j * 10 + k;
 21                 p++;
 22             }
 23             if (*p == ‘\0‘){
 24                 ip[l++] = j;
 25                 break;
 26             }
 27             ip[l++] = j;
 28             p++;
 29         }
 30     l = 0;
 31     printf("ip:\n");
 32     for (l=0; l < 4; l++)
 33         printf("%d ",ip[l]);
 34     printf("\n");
 35     l = 0;
 36     while (*net_addr_array[i] != ‘\0‘ )
 37     {
 38         p = net_addr_array[i];
 39         while (*p != ‘/‘)
 40         {
 41             j = 0;
 42             while (*p >= ‘0‘ && *p <= ‘9‘)
 43             {
 44                 int k = *p - ‘0‘;
 45                 j = j * 10 + k;
 46                 p++;
 47             }
 48             net[l++] = j;
 49             if (*p == ‘/‘)
 50                 break;
 51             p++;
 52         }
 53         p++;
 54         l = 0;
 55         while (*p != ‘\0‘)
 56         {
 57             j = 0;
 58             while (*p >= ‘0‘ && *p <= ‘9‘)
 59             {
 60                 int k = *p - ‘0‘;
 61                 j = j * 10 + k;
 62                 p++;
 63             }
 64             if (*p == ‘\0‘){
 65                 mask[l++] = j;
 66                 break;
 67             }
 68             mask[l++] = j;
 69             p++;
 70         }
 71         printf("\n");
 72         for (l=0; l < 4; l++)
 73             printf("%d ",net[l]);
 74         printf("/ ");
 75         for (l=0; l < 4; l++)
 76             printf("%d ",mask[l]);
 77         printf("\ncal ip & mask:\n");
 78         for (l=0; l < 4; l++)
 79         {
 80             printf(" %d ",ip[l]&mask[l]);
 81             if ((ip[l]&mask[l]) != net[l])
 82                 break;
 83             int temp = mask[l];
 84             while(temp)
 85             {
 86
 87                 if (temp & 0x00000001){
 88                     sum++;
 89                 }
 90                 temp = temp >> 1;
 91             }
 92         }
 93         if (l >= 4)
 94         {
 95             printf("\n前缀长度:%d",sum);
 96             if (len <= sum)
 97                 {
 98                     *n = i;
 99                     len = sum;
100                 }
101         }
102         sum = 0;
103         i++;
104         l = 0;
105         printf("\n");
106     }
107     printf("\n");
108 }
109 int main()
110 {
111     char ip_addr[20] = "192.168.1.100";
112
113     //ip_addr[13] = ‘\0‘;
114
115     const char *net_addr_array[100] =
116
117     {
118     "192.168.1.128/255.255.255.192",
119     "192.168.1.0/255.255.255.0",
120     "192.168.1.64/255.255.255.192",
121     "0.0.0.0/0.0.0.0",
122     ""
123     };
124     int *n;
125     n = (int*)malloc(sizeof(int));
126     max_prefix_match(ip_addr, net_addr_array, n);
127     printf("n = %d\n",*n);
128
129 }

时间: 2024-12-17 19:33:34

IP地址匹配的相关文章

正则表达式のip地址匹配の小见

对于IP地址我们先将其划分范围 对于每一个地址我们都将其划分成三段.每一段都确定它的范围 对于第一段它的范围是1-254 对于第二,三段它的范围是0-255 对于第四段它的范围是1-254 我们需要注意的是\b  与$ ^的区别 1\b强调的是在你的所查找的关键字中的位置  而  $^则是强调在你的关键字所匹配的行中的位置 2同时我们一样可以注意到 ifconfig  | egrep --color '\b([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[

多个ip地址匹配正则表达式

匹配规则:多个ip地址使用,号进行分割 例如:1.1.1.1,2.2.2.2var iplist =/^((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))|\*)((\/([012]\d|3[012]|\d))?)(,((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9

linux文本三剑客匹配网卡IP地址大PK(CentOS 7系统)

    运维工程师在做配置的过程中很多时候都需要去获取目标服务器网卡上的IP地址,那究竟用什么方式获取更便捷了,博主今天就带大家使用linux文本三剑客分别获取一下网卡的IP地址,最后我们再来对比一下. 实验环境: 系统:CentOS 7.2 网卡张数:双网卡 linux文本三剑客之grep 获取ifconfig输出中的IP地址 ifconfig | egrep -o "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-1][0-9]|22[0-3])\>.(\

C语言实现IP地址合法性检测和子网匹配

#include <stdio.h> #include <stdlib.h> #ifdef WIN32 #include <Winsock2.h> #else #include <fcntl.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <ar

使用正则表达式匹配IP地址

如何使用正则表达式匹配IP地址?这是很常见的任务.说难也难,说易也易,取决于在匹配的精确度以及正则表达式复杂度之间很好的折中. 通常,IP地址以点分十进制方式表示,IP地址分为4段,以点号分隔.要对IP地址进行匹配,首先要对其进行分析.0.0.0.0 - 255.255.255.255 一个简单的正则表达式: [0-9]+(?:\.[0-9]+){0,3} 或者 ^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$ 它能够完成我们的任务,但是像"3948.3.89.34238"

python中利用正则表达式匹配ip地址

现在有一道题目,要求利用python中re模块来匹配ip地址,我们应如何着手? 首先能想到的是ip地址是数字,正则表达式是如何匹配数字的呢? \d或[0-9] 对于这个问题,不要一下子上来就写匹配模式,应该一步步分解,把复杂的问题简单化 比如ip地址,我们可以总结一下规律 1. 它是一个字符串 2. 字符串内部是由4个1-3位的数字和3个.组成 3. 数字的范围是0-255 接下来,我们先试一下匹配第1个数字 第一步:尝试匹配192.168.100.123中的192 >>> import

linux中匹配正确的ip地址

1.假设IP地址是规范的,没有出错误的 sed -n "/[0-9]\{1,3\}.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/p" test 这种匹配存在明显的问题,在正则匹配的过程中,若是出现300,1,255,0:192.168.0.  :192.168,1.1.1这种错误的IP地址,任然会被匹配到 2.IP地址规范与否未知的情况下匹配 在这里,逛论坛的时候看见一位老哥踩了一个坑,这里做 一下记录 sed -n -r "/((([0

正则表达式匹配IP地址

'''首先分析ip地址的特征:255.255.255.255,前三位的数字处理基本一致 1位: 0-9              \d2位:10-99         [1-9]\d3位:100-199      1\d\d3位:200-249      2[0-4]\d3位:250-255      25[0-5] ''' 先匹配前三位数字: (\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]) 前三位加上 . ((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0

python 正则RE匹配IP地址

使用re库匹配IP地址 一.说明 ip地址为xxx.xxx.xxx.xxx,其中xxx为0-255直接数字. 本文匹配为(1-255).(0-255).(0-255).(1-254) 二.匹配表达式 1 ip_match = r"^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|0?[0-9]?[1-9])\.)(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){2}(?:25[0-4]|2[0-4][0-9]|1[0-9][0-