IP trie树接口

前两天其他项目组的同学说他们项目中的IP黑白名单要用到trie树,于是我好奇也自己实现了一个IP trie树接口.

在这里保存一下,方便备份以后使用,同时欢迎纠错和交流,希望有大神能指教更高效的算法.

1.头文件如下(iptrie.h)

 1 #ifndef _IP_TRIE_H_
 2 #define _IP_TIRE_H_
 3 
 4 #define SPLIT_SIGN "."
 5 #define IP_BINARY_LEN 32
 6 
 7 typedef struct ip_trie_node
 8 {
 9     struct ip_trie_node *child[2]; //two child node
10 }ip_trie_node;
11 
12 ip_trie_node *create_iptrie_node();
13 
14 void insert_iptrie_node(ip_trie_node *root,char ip[]);
15 
16 int select_iptrie_node(ip_trie_node *root,char ip[]);
17 
18 #endif

2.c文件如下(iptrie.c)

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 #include "iptrie.h"
  6 
  7 /*
  8  *name: itobinary
  9  *
 10  *param:
 11  * num: orignal number; binary_str: dest string; index: the binary str copy index
 12  *
 13  *return:
 14  * void
 15  */
 16 void itobinary(int num,char binary_str[],int index)
 17 {
 18     int i,bit = 0x01;
 19     for(i = 0; i < 8; i++)
 20     {//conver integer to 8 bit binary str
 21         if((num & bit) != 0)
 22         {//oprater & is lower than != 
 23             binary_str[index + 7 - i] = '1';
 24         }
 25         else
 26         {
 27             binary_str[index + 7 - i] = '0';
 28         }
 29         
 30         bit <<= 1; //bit * 2
 31     }
 32 }
 33 
 34 /*
 35  *name: convert_ip_binary
 36  *
 37  *param:
 38  * ip:orign ip string; binary_str:dest binary string
 39  *
 40  *return:
 41  * void
 42  */
 43 void convert_ip_binary(char ip[],char binary_str[])
 44 {
 45     char *ip_sub = NULL;
 46     int i,index =0;
 47     
 48     ip_sub = strtok(ip,SPLIT_SIGN); //slit ip by .
 49 
 50     itobinary(atoi(ip_sub),binary_str,index);
 51 
 52     for(i = 0; i < 3; i++)
 53     {//need to ip legal detect to pretend error
 54         ip_sub = strtok(NULL,SPLIT_SIGN);
 55         
 56         index += 8;
 57         itobinary(atoi(ip_sub),binary_str,index);
 58     }
 59 
 60 }
 61 
 62 /*
 63  *name: create_iptrie_node
 64  *
 65  *return:
 66  * new ip trie node
 67  */
 68 ip_trie_node *create_iptrie_node()
 69 {
 70     ip_trie_node *node = (ip_trie_node *)calloc(1,sizeof(ip_trie_node));
 71 
 72     if(node == NULL)
 73     {
 74         perror("create ip trie node error -- calloc");
 75     }
 76     else
 77     {
 78         node->child[0] = NULL;
 79         node->child[1] = NULL;
 80     }
 81 
 82     return node;
 83 }
 84 
 85 /*
 86  *name: insert_iptrie_node
 87  *
 88  *param:
 89  * root: trie root; ip: orignal ip string
 90  * 
 91  *return:
 92  * void
 93  *
 94  *notice:
 95  * this function call strtok it will change input ip
 96  * so if input ip need to use at other position
 97  * you shold input a copy of ip
 98  */
 99 void insert_iptrie_node(ip_trie_node *root,char ip[])
100 {
101     if(root == NULL)
102     {
103         printf("trie have not init\n");
104         
105         return;
106     }
107 
108     char binary_str[IP_BINARY_LEN + 1];
109     int i,child_index;
110     
111     memset(binary_str,0,IP_BINARY_LEN + 1);
112     
113     convert_ip_binary(ip,binary_str); //to binary string
114 
115     for(i = 0; i < IP_BINARY_LEN; i++)
116     {
117         child_index = binary_str[i] - '0'; //child is 0 or 1
118         if(root->child[child_index] == NULL)
119         {
120             root->child[child_index] = create_iptrie_node();
121         }
122         
123         root = root->child[child_index];
124     }
125 }
126 
127 /*
128  *name: select_iptrie_node
129  *
130  *param: 
131  * root: trie root; ip: orignal ip string
132  *
133  *return:
134  * 0 :not find; 1:find
135  *
136  *notice:
137  * this function call strtok it will change input ip
138  * so if input ip need to use at other position
139  * you shold input a copy of ip
140  */
141 int select_iptrie_node(ip_trie_node *root,char ip[])
142 {
143     if(root == NULL)
144     {
145         printf("trie have not init\n");
146         return 0;
147     }
148 
149     int i;
150     char binary_str[IP_BINARY_LEN + 1];
151 
152     memset(binary_str,0,IP_BINARY_LEN + 1);
153 
154     convert_ip_binary(ip,binary_str); //to binary string
155 
156     int child_index;
157     for(i = 0; i < IP_BINARY_LEN; i++)
158     {
159         child_index = binary_str[i] - '0';
160         
161         if(root->child[child_index] == NULL)
162         {
163             return 0;
164         }
165 
166         root = root->child[child_index];
167     }
168 
169     return 1;
170 }

3.main.c如下(测试程序)

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 #include "iptrie.h"
 5 
 6 
 7 int main()
 8 {
 9     char sip[16];
10     char dip[16];
11     int i = 0;
12     int isfind = 0;
13     ip_trie_node *root = create_iptrie_node();
14 
15     while(1)
16     {
17         printf("insert a ip:\n");
18         scanf("%s",sip);
19         insert_iptrie_node(root,sip);
20         
21         printf("query a ip:\n");
22         scanf("%s",dip);
23         isfind = select_iptrie_node(root,dip);
24         if(isfind == 1)
25         {
26             printf("find\n");
27         }
28         else
29         {
30             printf("not find\n");
31         }
32     }
33 }

4.Makefile (linux下编译)

CC = gcc
CFLAG = -g

INC = -I./

target:Iptrie

Iptrie:iptrie.o main.c
    $(CC) $(CFLAG) $(INC) -o $@  $^

iptrie.o:iptrie.c
    $(CC) -c $<

clean:
    rm *.o Iptrie

 

你可能感兴趣的:(IP trie树接口)