1
- // Package iploc provides fastest Geolocation Country library for Go.
1
+ // Package iploc provides fastest IP to Country library for Go.
2
2
//
3
3
// package main
4
4
//
5
5
// import (
6
6
// "fmt"
7
- // "net"
7
+ // "net/netip "
8
8
// "github.com/phuslu/iploc"
9
9
// )
10
10
//
11
11
// func main() {
12
- // fmt.Printf("%s", iploc.Country(net.ParseIP("2001:4860:4860::8888") ))
12
+ // fmt.Printf("%s", iploc.IPCountry(netip.MustParseAddr("1.1.1.1" ))
13
13
// }
14
14
//
15
15
// // Output: US
@@ -23,6 +23,7 @@ import (
23
23
"net"
24
24
"net/netip"
25
25
"os"
26
+ "reflect"
26
27
"sync"
27
28
"unsafe"
28
29
)
@@ -53,24 +54,26 @@ func IPCountry(ip netip.Addr) (country []byte) {
53
54
i = h + 1
54
55
}
55
56
}
56
- return ip4txt [i * 2 - 2 : i * 2 ]
57
+ // country = ip4txt[i*2-2 : i*2]
58
+ sh := (* reflect .SliceHeader )(unsafe .Pointer (& country ))
59
+ sh .Data = uintptr (unsafe .Add (unsafe .Pointer (& ip4txt [0 ]), uintptr (i * 2 - 2 )))
60
+ sh .Len = 2
61
+ sh .Cap = 2
62
+ return
57
63
}
58
64
59
65
ipv6once .Do (func () {
60
66
ipv4only = os .Getenv ("IPLOC_IPV4ONLY" ) != ""
61
- r , _ := gzip .NewReader (bytes .NewReader (ip6bin ))
62
- ip6bin , _ = io .ReadAll (r )
67
+ if ! ipv4only {
68
+ r , _ := gzip .NewReader (bytes .NewReader (ip6bin ))
69
+ ip6bin , _ = io .ReadAll (r )
70
+ }
63
71
})
64
72
65
73
if ipv4only {
66
74
return
67
75
}
68
76
69
- ipv6once .Do (func () {
70
- r , _ := gzip .NewReader (bytes .NewReader (ip6bin ))
71
- ip6bin , _ = io .ReadAll (r )
72
- })
73
-
74
77
b := ip .As16 ()
75
78
high := uint64 (b [0 ])<< 56 | uint64 (b [1 ])<< 48 | uint64 (b [2 ])<< 40 | uint64 (b [3 ])<< 32 | uint64 (b [4 ])<< 24 | uint64 (b [5 ])<< 16 | uint64 (b [6 ])<< 8 | uint64 (b [7 ])
76
79
low := uint64 (b [8 ])<< 56 | uint64 (b [9 ])<< 48 | uint64 (b [10 ])<< 40 | uint64 (b [11 ])<< 32 | uint64 (b [12 ])<< 24 | uint64 (b [13 ])<< 16 | uint64 (b [14 ])<< 8 | uint64 (b [15 ])
@@ -84,7 +87,12 @@ func IPCountry(ip netip.Addr) (country []byte) {
84
87
i = h + 2
85
88
}
86
89
}
87
- return ip6txt [i - 2 : i ]
90
+ // country = ip6txt[i-2 : i]
91
+ sh := (* reflect .SliceHeader )(unsafe .Pointer (& country ))
92
+ sh .Data = uintptr (unsafe .Add (unsafe .Pointer (& ip6txt [0 ]), uintptr (i - 2 )))
93
+ sh .Len = 2
94
+ sh .Cap = 2
95
+ return
88
96
}
89
97
90
98
// Country return ISO 3166-1 alpha-2 country code of IP.
0 commit comments