Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit a374453

Browse files
VenaMoyeHenryGessau
authored andcommitted
IPSet Intersection (#2)
* Added a function to check the intersection of IPSets * Added a function to check IPSet intersection and a function to test it * small tweaks to make sure the code is organized * Added more test cases * Fixed tests cases * changed an invalid IP * updated test cases * Changed function name
1 parent 3e50d74 commit a374453

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

ipset.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,28 @@ func (s *IPSet) GetIPs(limit int) (ips []net.IP) {
113113
}
114114
return
115115
}
116+
117+
// Intersection computes the set intersect between this IPSet and another one
118+
// It returns a new set which is the intersection.
119+
func (s *IPSet) Intersection(set1 *IPSet) (interSect *IPSet) {
120+
interSect = &IPSet{}
121+
s.tree.walk(func(node *ipTree) {
122+
if set1.ContainsNet(node.net) {
123+
interSect.InsertNet(node.net)
124+
}
125+
})
126+
set1.tree.walk(func(node *ipTree) {
127+
if s.ContainsNet(node.net) {
128+
interSect.InsertNet(node.net)
129+
}
130+
})
131+
return
132+
}
133+
134+
// String returns a list of IP Networks
135+
func (s *IPSet) String() (str []string) {
136+
for node := s.tree.first(); node != nil; node = node.next() {
137+
str = append(str, node.net.String())
138+
}
139+
return
140+
}

ipset_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,93 @@ func TestIPSetDifference(t *testing.T) {
236236
assert.False(t, set.ContainsNet(cidr))
237237
}
238238

239+
func TestIntersectionAinB1(t *testing.T) {
240+
case1 := []string{"10.0.16.0/20", "10.5.8.0/24", "10.23.224.0/23"}
241+
case2 := []string{"10.0.20.0/30", "10.5.8.0/29", "10.23.224.0/27"}
242+
output := []string{"10.23.224.0/27", "10.0.20.0/30", "10.5.8.0/29"}
243+
testIntersection(t, case1, case2, output)
244+
245+
}
246+
247+
func TestIntersectionAinB2(t *testing.T) {
248+
case1 := []string{"10.10.0.0/30", "10.5.8.0/29", "10.23.224.0/27"}
249+
case2 := []string{"10.10.0.0/20", "10.5.8.0/24", "10.23.224.0/23"}
250+
output := []string{"10.10.0.0/30", "10.5.8.0/29", "10.23.224.0/27"}
251+
testIntersection(t, case1, case2, output)
252+
}
253+
254+
func TestIntersectionAinB3(t *testing.T) {
255+
case1 := []string{"10.0.5.0/24", "10.5.8.0/29", "10.23.224.0/27"}
256+
case2 := []string{"10.6.0.0/24", "10.9.9.0/29", "10.23.6.0/23"}
257+
output := []string{}
258+
testIntersection(t, case1, case2, output)
259+
}
260+
261+
func TestIntersectionAinB4(t *testing.T) {
262+
case1 := []string{"10.23.6.0/24", "10.5.8.0/29", "10.23.224.0/27"}
263+
case2 := []string{"10.6.0.0/24", "10.9.9.0/29", "10.23.6.0/29"}
264+
output := []string{"10.23.6.0/29"}
265+
testIntersection(t, case1, case2, output)
266+
}
267+
268+
func TestIntersectionAinB5(t *testing.T) {
269+
case1 := []string{"2001:db8:0:23::/96", "2001:db8:0:20::/96", "2001:db8:0:15::/96"}
270+
case2 := []string{"2001:db8:0:23::/64", "2001:db8:0:20::/64", "2001:db8:0:15::/64"}
271+
output := []string{"2001:db8:0:23::/96", "2001:db8:0:20::/96", "2001:db8:0:15::/96"}
272+
testIntersection(t, case1, case2, output)
273+
}
274+
275+
func TestIntersectionAinB6(t *testing.T) {
276+
case1 := []string{"2001:db8:0:23::/64", "2001:db8:0:20::/64", "2001:db8:0:15::/64"}
277+
case2 := []string{"2001:db8:0:23::/96", "2001:db8:0:20::/96", "2001:db8:0:15::/96"}
278+
output := []string{"2001:db8:0:15::/96", "2001:db8:0:20::/96", "2001:db8:0:23::/96"}
279+
testIntersection(t, case1, case2, output)
280+
}
281+
282+
func TestIntersectionAinB7(t *testing.T) {
283+
case1 := []string{"2001:db8:0:23::/64", "2001:db8:0:20::/64", "2001:db8:0:15::/64"}
284+
case2 := []string{"2001:db8:0:14::/96", "2001:db8:0:10::/96", "2001:db8:0:8::/96"}
285+
output := []string{}
286+
testIntersection(t, case1, case2, output)
287+
}
288+
289+
func TestIntersectionAinB8(t *testing.T) {
290+
case1 := []string{"2001:db8:0:23::/64", "2001:db8:0:20::/64", "172.16.1.0/24"}
291+
case2 := []string{"2001:db9:0:14::/96", "2001:db9:0:10::/96", "172.16.1.0/28"}
292+
output := []string{"172.16.1.0/28"}
293+
testIntersection(t, case1, case2, output)
294+
}
295+
296+
func TestIntersectionAinB9(t *testing.T) {
297+
case1 := []string{"10.5.8.0/29"}
298+
case2 := []string{"10.10.0.0/20", "10.5.8.0/24", "10.23.224.0/23"}
299+
output := []string{"10.5.8.0/29"}
300+
testIntersection(t, case1, case2, output)
301+
}
302+
303+
func testIntersection(t *testing.T, input1 []string, input2 []string, output []string) {
304+
set1, set2, interSect := &IPSet{}, &IPSet{}, &IPSet{}
305+
for i := 0; i < len(input1); i++ {
306+
cidr, _ := ParseNet(input1[i])
307+
set1.InsertNet(cidr)
308+
}
309+
for j := 0; j < len(input2); j++ {
310+
cidr, _ := ParseNet(input2[j])
311+
set2.InsertNet(cidr)
312+
}
313+
for k := 0; k < len(output); k++ {
314+
cidr, _ := ParseNet(output[k])
315+
interSect.InsertNet(cidr)
316+
}
317+
set := set1.Intersection(set2)
318+
s1 := set.String()
319+
intSect := interSect.String()
320+
if !assert.Equal(t, intSect, s1) {
321+
t.Logf("\nEXPECTED: %s\nACTUAL: %s\n", intSect, s1)
322+
}
323+
324+
}
325+
239326
func TestIPSetInsertV6(t *testing.T) {
240327
set := IPSet{}
241328

0 commit comments

Comments
 (0)