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     if(binary_str == NULL)
 19     {
 20         return;
 21     }
 22 
 23     int i,bit = 0x01;
 24     for(i = 0; i < 8; i++)
 25     {//conver integer to 8 bit binary str
 26         if((num & bit) != 0)
 27         {//oprater & is lower than != 
 28             binary_str[index + 7 - i] = '1';
 29         }
 30         else
 31         {
 32             binary_str[index + 7 - i] = '0';
 33         }
 34         
 35         bit <<= 1; //bit * 2
 36     }
 37 }
 38 
 39 /*
 40  *name: convert_ip_binary
 41  *
 42  *param:
 43  * ip:orign ip string; binary_str:dest binary string
 44  *
 45  *return:
 46  * void
 47  */
 48 void convert_ip_binary(char ip[],char binary_str[])
 49 {
 50     if(ip == NULL || binary_str == NULL)
 51     {
 52         return;
 53     }
 54     
 55     /*为确保正确性在进行转换之前可以进一步进行IP格式校验*/
 56 
 57     char *ip_sub = NULL;
 58     int i,index =0;
 59     
 60     ip_sub = strtok(ip,SPLIT_SIGN); //slit ip by .
 61 
 62     itobinary(atoi(ip_sub),binary_str,index);
 63 
 64     for(i = 0; i < 3; i++)
 65     {//need to ip legal detect to pretend error
 66         ip_sub = strtok(NULL,SPLIT_SIGN);
 67         
 68         index += 8;
 69         itobinary(atoi(ip_sub),binary_str,index);
 70     }
 71 
 72 }
 73 
 74 /*
 75  *name: create_iptrie_node
 76  *
 77  *return:
 78  * new ip trie node
 79  */
 80 ip_trie_node *create_iptrie_node()
 81 {
 82     ip_trie_node *node = (ip_trie_node *)calloc(1,sizeof(ip_trie_node));
 83 
 84     if(node == NULL)
 85     {
 86         perror("create ip trie node error -- calloc");
 87     }
 88     else
 89     {
 90         node->child[0] = NULL;
 91         node->child[1] = NULL;
 92     }
 93 
 94     return node;
 95 }
 96 
 97 /*
 98  *name: insert_iptrie_node
 99  *
100  *param:
101  * root: trie root; ip: orignal ip string
102  * 
103  *return:
104  * void
105  *
106  *notice:
107  * this function call strtok it will change input ip
108  * so if input ip need to use at other position
109  * you shold input a copy of ip
110  */
111 void insert_iptrie_node(ip_trie_node *root,char ip[])
112 {
113     if(root == NULL)
114     {
115         printf("trie have not init\n");
116         
117         return;
118     }
119 
120     if(ip == NULL)
121     {
122         return;
123     }
124 
125     char binary_str[IP_BINARY_LEN + 1];
126     int i,child_index;
127     
128     memset(binary_str,0,IP_BINARY_LEN + 1);
129     
130     convert_ip_binary(ip,binary_str); //to binary string
131 
132     for(i = 0; i < IP_BINARY_LEN; i++)
133     {
134         child_index = binary_str[i] - '0'; //child is 0 or 1
135         if(root->child[child_index] == NULL)
136         {
137             root->child[child_index] = create_iptrie_node();
138         }
139         
140         root = root->child[child_index];
141     }
142 }
143 
144 /*
145  *name: select_iptrie_node
146  *
147  *param: 
148  * root: trie root; ip: orignal ip string
149  *
150  *return:
151  * 0 :not find; 1:find
152  *
153  *notice:
154  * this function call strtok it will change input ip
155  * so if input ip need to use at other position
156  * you shold input a copy of ip
157  */
158 int select_iptrie_node(ip_trie_node *root,char ip[])
159 {
160     if(root == NULL)
161     {
162         printf("trie have not init\n");
163         return 0;
164     }
165 
166     if(ip == NULL)
167     {
168         return 0;
169     }
170 
171     int i;
172     char binary_str[IP_BINARY_LEN + 1];
173 
174     memset(binary_str,0,IP_BINARY_LEN + 1);
175 
176     convert_ip_binary(ip,binary_str); //to binary string
177 
178     int child_index;
179     for(i = 0; i < IP_BINARY_LEN; i++)
180     {
181         child_index = binary_str[i] - '0';
182         
183         if(root->child[child_index] == NULL)
184         {
185             return 0;
186         }
187 
188         root = root->child[child_index];
189     }
190 
191     return 1;
192 }

 

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

 

    原文作者:Trie树
    原文地址: https://blog.csdn.net/code_mover/article/details/51863611
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞