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

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

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

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
void max_prefix_match(const char *ip_addr, const char *net_addr_array[], int *n)
{
int i,j,ip[],mask[],l,len,net[],sum;
const char *p;
i = ;
l = ;
sum = ;
len = ;
*n = -;
p = ip_addr;
while (*p != '\0')
{
j = ;
while (*p >= '' && *p <= '')
{
int k = *p - '';
j = j * + k;
p++;
}
if (*p == '\0'){
ip[l++] = j;
break;
}
ip[l++] = j;
p++;
}
l = ;
printf("ip:\n");
for (l=; l < ; l++)
printf("%d ",ip[l]);
printf("\n");
l = ;
while (*net_addr_array[i] != '\0' )
{
p = net_addr_array[i];
while (*p != '/')
{
j = ;
while (*p >= '' && *p <= '')
{
int k = *p - '';
j = j * + k;
p++;
}
net[l++] = j;
if (*p == '/')
break;
p++;
}
p++;
l = ;
while (*p != '\0')
{
j = ;
while (*p >= '' && *p <= '')
{
int k = *p - '';
j = j * + k;
p++;
}
if (*p == '\0'){
mask[l++] = j;
break;
}
mask[l++] = j;
p++;
}
printf("\n");
for (l=; l < ; l++)
printf("%d ",net[l]);
printf("/ ");
for (l=; l < ; l++)
printf("%d ",mask[l]);
printf("\ncal ip & mask:\n");
for (l=; l < ; l++)
{
printf(" %d ",ip[l]&mask[l]);
if ((ip[l]&mask[l]) != net[l])
break;
int temp = mask[l];
while(temp)
{ if (temp & 0x00000001){
sum++;
}
temp = temp >> ;
}
}
if (l >= )
{
printf("\n前缀长度:%d",sum);
if (len <= sum)
{
*n = i;
len = sum;
}
}
sum = ;
i++;
l = ;
printf("\n");
}
printf("\n");
}
int main()
{
char ip_addr[] = "192.168.1.100"; //ip_addr[13] = '\0'; const char *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",
""
};
int *n;
n = (int*)malloc(sizeof(int));
max_prefix_match(ip_addr, net_addr_array, n);
printf("n = %d\n",*n); }

IP地址匹配的更多相关文章

  1. 多个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}( ...

  2. [置顶] 正则表达式应用:匹配IP地址

    都知道iP地址有四个数值,三个点号组成.三个数值的具体范围为0到255,为了使用正则表达式匹配就必须分析IP地址的组成 1先分析数值,2再组合数值和点号 1先分析数值 IP地址的数字范围从0到255, ...

  3. 用正则匹配一串字符串中的ip地址

    IP地址有4段组成,每一段数字的范围为0-255,在一段文本中提取ip地址可以这样 $src = 'src = alsdlk ks sdf2.3.3.4 234.193.1.120.1232 d.23 ...

  4. 匹配合法IP地址的正则表达式

    IPV4地址分为4段,以点号分隔.如192.168.26.13.要对IP地址进行匹配,首先要对其进行分析,分成如下部分,分别进行匹配: 第一步:地址分析,正则初判 0-9      \d 进行匹配 1 ...

  5. linux中匹配正确的ip地址

    1.假设IP地址是规范的,没有出错误的 sed -n "/[0-9]\{1,3\}.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/p" test ...

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

    IP地址分为4段,以点号分隔.要对IP地址进行匹配,首先要对其进行分析,分成如下部分,分别进行匹配:   第一步:地址分析,正则初判 1.0-9 \d 进行匹配 2.10-99 [1-9]\d 进行匹 ...

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

    现在有一道题目,要求利用python中re模块来匹配ip地址,我们应如何着手? 首先能想到的是ip地址是数字,正则表达式是如何匹配数字的呢? \d或[0-9] 对于这个问题,不要一下子上来就写匹配模式 ...

  8. 正则表达式通用匹配ip地址及主机检测

    在使用正则表达式匹配ip地址时如果不限定ip正确格式,一些场景下可能会产生不一样的结果,比如ip数值超范围,ip段超范围等,在使用正则表达式匹配ip地址时要注意几点: 1,字符界定:使用  \< ...

  9. python匹配ip地址

    ip地址是用3个'.'号作为分隔符,分割4个数字,每个数字的取值在[0,255],一般日志文件中的ip地址都是有效的ip地址,不需要我们再去验证,因此,若从日志文件中提取ip,那么可以简单写成这样: ...

随机推荐

  1. Compress a Folder/Directory via Perl5

    Compress a Folder/Directory via Perl5 tested in Windows, Mac OS X, Ubuntu16.04 #!/usr/bin/perl #压缩指定 ...

  2. javascript,jquery代码规范

    jquery代码规范 Coding Standards & Best Practices 中文翻译版:jquery编程的标准写法和最佳实践 javascript代码规范 JavaScript编 ...

  3. PHP自定义函数格式化json数据怎么调用?

    <?php/*** Formats a JSON string for pretty printing** @param string $json The JSON to make pretty ...

  4. ubuntu-E:Encountered a section with no Package: header的解决办法

    刚才打开ubuntu,我的版本是12.04.正想使用sudo apt-get install build-essential 时,出现了如下错误: E:Encountered a section wi ...

  5. IOS中两个view的切换

    在ios中,rootview为PassWordViewController,secondview为SecondViewController,实现在rootview中听过一个跳转按钮实现跳转到secon ...

  6. YTU 2973: C语言习题5.25--文件操作2

    2973: C语言习题5.25--文件操作2 时间限制: 1 Sec  内存限制: 128 MB 提交: 242  解决: 105 题目描述 文本文件score.dic 中存储了n名学生的信息(班级编 ...

  7. SlickGrid example 3b: 支持撤销操作的编辑单元

    不同类型的属性可以按不同的风格编辑. 每个编辑单元可以设置不同的验证方法. 历史编辑可以撤销.   代码: <!DOCTYPE html PUBLIC "-//W3C//DTD HTM ...

  8. poj1222 EXTENDED LIGHTS OUT

    设输入矩阵为A,输出矩阵为B,目标矩阵为C(零矩阵). 方便起见,矩阵行列下标均从1开始. 考虑A矩阵元素a(i,j),B矩阵中与其相邻的元素 b(i,j),b(i - 1, j),b(i + 1,j ...

  9. Linux高级变量

    http://blog.chinaunix.net/uid-27040051-id-3450991.html 高级变量 基本形式 [1].变量扩展 格式 ${变量名称} [2].命令扩展 格式 $(命 ...

  10. CountDownLatch、CyclicBarrier和Semaphore

    转载:http://www.cnblogs.com/dolphin0520/p/3920397.html 在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDown ...