File tree 9 files changed +66
-86
lines changed
9 files changed +66
-86
lines changed Original file line number Diff line number Diff line change 1
1
MIT License
2
2
3
- Copyright (c) 2019 Phus Lu
3
+ Copyright (c) 2020 Phus Lu
4
4
5
5
Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
of this software and associated documentation files (the "Software"), to deal
Original file line number Diff line number Diff line change 1
- # geoip - fast geoip country library
1
+ # geoip - fastest geoip country library
2
2
3
3
[ ![ godoc] ( http://img.shields.io/badge/godoc-reference-blue.svg?style=flat )] ( https://godoc.org/github.com/phuslu/geoip ) [ ![ license] ( http://img.shields.io/badge/license-MIT-red.svg?style=flat )] ( https://raw.githubusercontent.com/phuslu/geoip/master/LICENSE ) [ ![ goreport] ( https://goreportcard.com/badge/github.com/phuslu/geoip )] ( https://goreportcard.com/report/github.com/phuslu/geoip ) [ ![ coverage] ( https://img.shields.io/badge/coverage-100%25-brightgreen )] ( https://gocover.io/github.com/phuslu/geoip )
4
4
8
8
package main
9
9
10
10
import (
11
+ " fmt"
11
12
" net"
12
13
" github.com/phuslu/geoip"
13
14
)
14
15
15
16
func main () {
16
- println ( string ( geoip.Country (net.ParseIP (" 2001:4860:4860::8888" ) )))
17
+ fmt. Printf ( " %s " , geoip.Country (net.ParseIP (" 2001:4860:4860::8888" )))
17
18
}
18
19
19
20
// Output: US
20
21
```
21
22
22
23
### Benchmarks
23
24
```
24
- BenchmarkGeoIpCountryForIPv4-8 35.2 ns/op 0 B/op 0 allocs/op
25
- BenchmarkGeoIpCountryForIPv6-8 43.6 ns/op 0 B/op 0 allocs/op
25
+ BenchmarkGeoIpCountryForIPv4-8 20.8 ns/op 0 B/op 0 allocs/op
26
+ BenchmarkGeoIpCountryForIPv6-8 38.2 ns/op 0 B/op 0 allocs/op
26
27
```
27
28
28
29
### Acknowledgment
Original file line number Diff line number Diff line change 1
1
// Package geoip provides fastest GeoIP Country library for Go.
2
2
//
3
- // eg.
4
- //
5
- // country := geoip.Country(net.ParseIP("1.1.1.1"))
6
- // fmt.Printf("%s\n", country)
3
+ // fmt.Printf("%s\n", geoip.Country(net.ParseIP("1.1.1.1")))
7
4
//
8
5
// // Output: US
9
6
package geoip
@@ -13,31 +10,41 @@ import (
13
10
"net"
14
11
)
15
12
16
- // Country find iso3166 country code of IP.
13
+ // Country find ISO 3166-1 alpha-2 country code of IP.
17
14
func Country (ip net.IP ) (country []byte ) {
18
15
if ip == nil {
19
16
return
20
17
}
18
+
21
19
if ip4 := ip .To4 (); ip4 != nil {
22
- country = country4 (binary .BigEndian .Uint32 (ip4 ))
20
+ // ipv4
21
+ n := binary .BigEndian .Uint32 (ip4 )
22
+ i , j := 0 , len (ips )
23
+ for i < j {
24
+ h := (i + j ) >> 1
25
+ if ips [h ] > n {
26
+ j = h
27
+ } else {
28
+ i = h + 1
29
+ }
30
+ }
31
+ country = geo [i << 1 - 2 : i << 1 ]
23
32
} else {
24
- country = country6 (binary .BigEndian .Uint64 (ip ), binary .BigEndian .Uint64 (ip [8 :]))
25
- }
26
- return
27
- }
28
-
29
- func country4 (n uint32 ) (country []byte ) {
30
- i , j := 0 , len (ips )
31
- for i < j {
32
- h := int (uint (i + j ) >> 1 )
33
- if ips [h ] <= n {
34
- i = h + 1
35
- } else {
36
- j = h
33
+ // ipv6
34
+ high := binary .BigEndian .Uint64 (ip )
35
+ low := binary .BigEndian .Uint64 (ip [8 :])
36
+ i , j := 0 , len (ips6 )
37
+ for i < j {
38
+ h := (i + j ) >> 1 & ^ 0xf
39
+ n := ip6uint (h )
40
+ if n > high || (n == high && ip6uint (h + 8 ) > low ) {
41
+ j = h
42
+ } else {
43
+ i = h + 16
44
+ }
37
45
}
46
+ country = geo6 [i >> 3 - 2 : i >> 3 ]
38
47
}
39
48
40
- country = geo [i * 2 - 2 : i * 2 ]
41
-
42
49
return
43
50
}
Load Diff This file was deleted.
Load Diff This file was deleted.
Original file line number Diff line number Diff line change 1
- 8f11b974f898b3938be68810f1d244d6603ff4dc
1
+ b25db6cfc8619db0925d4a5b0bd7bfd10a4108c1
Original file line number Diff line number Diff line change @@ -54,12 +54,12 @@ func TestGeoIpCountry(t *testing.T) {
54
54
}
55
55
56
56
func BenchmarkGeoIpCountryForIPv4 (b * testing.B ) {
57
- ip := net .ParseIP ( "8.8.8.8" )
57
+ ip := net.IP { 8 , 8 , 8 , 8 }
58
58
59
59
b .ReportAllocs ()
60
60
b .ResetTimer ()
61
61
for i := 0 ; i < b .N ; i ++ {
62
- Country (net . IP ( ip ) )
62
+ Country (ip )
63
63
}
64
64
}
65
65
Original file line number Diff line number Diff line change
1
+ // +build !386
2
+ // +build !amd64
3
+ // +build !amd64p32
4
+ // +build !arm64
5
+ // +build !ppc64le
6
+ // +build !mipsle
7
+ // +build !mips64le
8
+ // +build !mips64p32le
9
+
10
+ package geoip
11
+
12
+ import (
13
+ "encoding/binary"
14
+ )
15
+
16
+ func ip6uint (i int ) uint64 {
17
+ return binary .LittleEndian .Uint64 (ips6 [i :])
18
+ }
Original file line number Diff line number Diff line change
1
+ // +build 386 amd64 amd64p32 arm64 ppc64le mipsle mips64le mips64p32le
2
+
3
+ package geoip
4
+
5
+ import (
6
+ "unsafe"
7
+ )
8
+
9
+ func ip6uint (i int ) uint64 {
10
+ return * (* uint64 )(unsafe .Pointer (& ips6 [i ]))
11
+ }
You can’t perform that action at this time.
0 commit comments