Closed thinkeridea closed 4 years ago
package exnet
import (
"net"
"testing"
)
// HasLocalIPddr 检测 IP 地址字符串是否是内网地址
func HasLocalIPddr(ip string) bool {
return HasLocalIP(net.ParseIP(ip))
}
// HasLocalIP 检测 IP 地址是否是内网地址
// 通过直接对比ip段范围效率更高,详见:https://github.com/thinkeridea/go-extend/issues/2
func HasLocalIP(ip net.IP) bool {
if ip.IsLoopback() {
return true
}
ip4 := ip.To4()
if ip4 == nil {
return false
}
return ip4[0] == 10 || // 10.0.0.0/8
(ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31) || // 172.16.0.0/12
(ip4[0] == 169 && ip4[1] == 254) || // 169.254.0.0/16
(ip4[0] == 192 && ip4[1] == 168) // 192.168.0.0/16
}
// 收集的内网网络地址 IP 段
var localNetworks []*net.IPNet
func init() {
localNetworks = make([]*net.IPNet, 4)
for i, sNetwork := range []string{
"10.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"192.168.0.0/16",
} {
_, network, _ := net.ParseCIDR(sNetwork)
localNetworks[i] = network
}
}
// HasLocalIPddr 检测 IP 地址字符串是否是内网地址
func HasLocalIPddr_test(ip string) bool {
return HasLocalIP_test(net.ParseIP(ip))
}
// HasLocalIP 检测 IP 地址是否是内网地址
func HasLocalIP_test(ip net.IP) bool {
for _, network := range localNetworks {
if network.Contains(ip) {
return true
}
}
return ip.IsLoopback()
}
func BenchmarkHasLocalIP(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, ip := range []string{
"192.168.9.18",
"10.168.9.18",
"172.16.9.18",
"172.17.9.18",
"172.18.9.18",
"172.19.9.18",
"172.20.9.18",
"172.21.9.18",
"172.22.9.18",
"172.23.9.18",
"172.24.9.18",
"172.25.9.18",
"172.26.9.18",
"172.27.9.18",
"172.28.9.18",
"172.29.9.18",
"172.30.9.18",
"172.31.9.18",
} {
if !HasLocalIPddr_test(ip) {
b.Fatal(ip)
}
}
}
}
func BenchmarkHasLocalIP2(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, ip := range []string{
"192.168.9.18",
"10.168.9.18",
"172.16.9.18",
"172.17.9.18",
"172.18.9.18",
"172.19.9.18",
"172.20.9.18",
"172.21.9.18",
"172.22.9.18",
"172.23.9.18",
"172.24.9.18",
"172.25.9.18",
"172.26.9.18",
"172.27.9.18",
"172.28.9.18",
"172.29.9.18",
"172.30.9.18",
"172.31.9.18",
} {
if !HasLocalIPddr(ip) {
b.Fatal(ip)
}
}
}
}
测试结果:
$ go test -benchmem -bench="." ip*.go
goos: darwin
goarch: amd64
BenchmarkHasLocalIP-8 441862 2273 ns/op 288 B/op 18 allocs/op
BenchmarkHasLocalIP2-8 801446 1502 ns/op 288 B/op 18 allocs/op
PASS
ok command-line-arguments 2.268s
172.16~31.0.0/12
其掩码地址均为172.16.0.0/12
存在重复。使用直接对比ip段前两段数据检查,不使用
network.Contains
判断,在暂时不支持IPV6
的前提下,这种方法更加高效。