Chinaunix首页 | 论坛 | 博客
  • 博客访问: 404911
  • 博文数量: 35
  • 博客积分: 943
  • 博客等级: 准尉
  • 技术积分: 742
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-15 13:17
个人简介

积累知识,方便自己

文章分类

全部博文(35)

文章存档

2014年(2)

2013年(5)

2012年(13)

2011年(15)

分类: C/C++

2014-05-29 11:41:32

本文主要对ip信息五元组的key值计算进行说明
常见的hash算法步骤:
    1. 初始化hash数组,如char *a[200];
    2. 对需要存储的数据求hash的key
        求key值的得法一般有:
        1) 利用异或,然后求模得到key
        2) 利用crc32,crc16,sha,md5等进行key值计算
        3) 其他
    3. 在相应的key值位置分配内存,并存储数据
        如:得到的key为100,那么a[100]=malloc(...),存储数据
crc算法是用来校验使用,可以自行查看crc算法的一些介绍,目前利用此算法进行hash也不少,本方法提出crc20算法来进行hash计算,crc的生成多项式有下:

而本文的crc20的多项式为:x^20+x^12+x^8+1,简记式为:01101;
利用此多项式来计算五元组(源IP 源端口 目的IP 目的端口 协议)的hash,取得计算得来的值的后20位作为key值:
1.假设五元组结构如下:

点击(此处)折叠或打开

  1. typedef struct pkt_info{
  2.     unsigned int srcip;
  3.     unsigned short sport;
  4.     unsigned int dstip;
  5.     unsigned short dport;
  6.     unsigned short proto;
  7. }pkt_info;
2.计算key值:

点击(此处)折叠或打开

  1. pkt_info ptf;
  2. unsigned int key=0;
  3. /*假设此结构里面的数据*/
  4. ptf.srcip=...
  5. ptf.sport=...
  6. ptf.dstip=...
  7. ptf.dport=...
  8. ptf.proto=...
  9. /*计算key*/
  10. key=CRC20_key((unsigned char *)&ptf,sizeof(pkt_info));
3. CRC20_key函数的定义实现:

点击(此处)折叠或打开

  1. #define POLY 0x01101 // CRC20生成多项式x^20+x^12+x^8+1即:01101 CRC32:04C11DB7L
  2. static unsigned int crc_table[256];
  3. unsigned int get_sum_poly(unsigned char data)
  4. {
  5.     unsigned int sum_poly = data;
  6.     int j;
  7.     sum_poly <<= 24;
  8.     for(j = 0; j < 8; j++)
  9.     {
  10.         int hi = sum_poly&0x80000000; // 取得reg的最高位
  11.         sum_poly <<= 1;
  12.         if(hi) sum_poly = sum_poly^POLY;
  13.     }
  14.     return sum_poly;
  15. }
  16. void create_crc_table(void)  //在使用CRC20_key函数应该先建立crc表
  17. {
  18.     int i;
  19.     for(i = 0; i < 256; i++)
  20.     {
  21.     crc_table[i] = get_sum_poly(i&0xFF);
  22.     }
  23. }
  24. unsigned int CRC20_key(unsigned char* data, int len)
  25. {
  26.     int i;
  27.     unsigned int reg = 0xFFFFFFFF;// 0xFFFFFFFF,见后面解释
  28.     for(i = 0; i < len; i++)
  29.     {
  30.         reg = (reg<<8) ^ crc_table[(reg>>24)&0xFF ^ data[i]];
  31.     }
  32.     return (reg&0XFFFFF);//得到的reg取后20作为key值
  33. }
注:初始化hash数组大小确定:
#define maxhash    1<<20
pkt_info *root
root=malloc(maxhash * sizeof(pkt_info *));

冲突的解决方法可以采用链表方式,即同一个key值位置元素不同,在此位置用链表向后连接,可以查看linux的内核链表,或者自己实现
阅读(12515) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~