英文:
Go/GoLang check IP address in range
问题
在Go/GoLang中,检查IP地址是否在特定范围内的最快方法是什么?
例如,给定范围为216.14.49.184
到216.14.49.191
,我该如何检查给定的输入IP地址是否在该范围内?
英文:
In Go/GoLang, what is the fastest way to check if an IP address is in a specific range?
For example, given range 216.14.49.184
to 216.14.49.191
, how would I check if a given input IP address is in that range?
答案1
得分: 46
IP地址在Go语言中以大端字节切片([]byte
)的形式表示(使用IP
类型),因此可以使用bytes.Compare
进行正确比较。
例如(play)
package main
import (
"bytes"
"fmt"
"net"
)
var (
ip1 = net.ParseIP("216.14.49.184")
ip2 = net.ParseIP("216.14.49.191")
)
func check(ip string) bool {
trial := net.ParseIP(ip)
if trial.To4() == nil {
fmt.Printf("%v 不是一个IPv4地址\n", trial)
return false
}
if bytes.Compare(trial, ip1) >= 0 && bytes.Compare(trial, ip2) <= 0 {
fmt.Printf("%v 在 %v 和 %v 之间\n", trial, ip1, ip2)
return true
}
fmt.Printf("%v 不在 %v 和 %v 之间\n", trial, ip1, ip2)
return false
}
func main() {
check("1.2.3.4")
check("216.14.49.185")
check("1::16")
}
输出结果为:
1.2.3.4 不在 216.14.49.184 和 216.14.49.191 之间
216.14.49.185 在 216.14.49.184 和 216.14.49.191 之间
1::16 不是一个IPv4地址
英文:
IP addresses are represented as bigendian []byte
slices in go (the IP
type) so will compare correctly using bytes.Compare
.
Eg (play)
package main
import (
"bytes"
"fmt"
"net"
)
var (
ip1 = net.ParseIP("216.14.49.184")
ip2 = net.ParseIP("216.14.49.191")
)
func check(ip string) bool {
trial := net.ParseIP(ip)
if trial.To4() == nil {
fmt.Printf("%v is not an IPv4 address\n", trial)
return false
}
if bytes.Compare(trial, ip1) >= 0 && bytes.Compare(trial, ip2) <= 0 {
fmt.Printf("%v is between %v and %v\n", trial, ip1, ip2)
return true
}
fmt.Printf("%v is NOT between %v and %v\n", trial, ip1, ip2)
return false
}
func main() {
check("1.2.3.4")
check("216.14.49.185")
check("1::16")
}
Which produces
1.2.3.4 is NOT between 216.14.49.184 and 216.14.49.191
216.14.49.185 is between 216.14.49.184 and 216.14.49.191
1::16 is not an IPv4 address
答案2
得分: 38
这已经在标准库的"net"包中作为一个名为net.Contains的函数存在。你不需要重写已经存在的代码!
请参阅此处的文档。
要使用它,你只需要解析所需的子网:
network := "192.168.5.0/24"
clientips := []string{
"192.168.5.1",
"192.168.6.0",
}
_, subnet, _ := net.ParseCIDR(network)
for _, clientip := range clientips {
ip := net.ParseIP(clientip)
if subnet.Contains(ip) {
fmt.Println("IP in subnet", clientip)
}
}
如果上面的代码不清楚,请查看golang play链接。
英文:
This is already in the stdlib in the "net" package as a function called net.Contains. You dont need to rewrite code that already exists!
See documentation here.
To use it you just have to parse the desired subnets
network := "192.168.5.0/24"
clientips := []string{
"192.168.5.1",
"192.168.6.0",
}
_, subnet, _ := net.ParseCIDR(network)
for _, clientip := range clientips {
ip := net.ParseIP(clientip)
if subnet.Contains(ip) {
fmt.Println("IP in subnet", clientip)
}
}
In case the above code doesn't make sense here is a golang play link
答案3
得分: 7
ipv4/ipv6的通用版本。
ip.go:
package ip
import (
"bytes"
"net"
"github.com/golang/glog"
)
// 判断给定的IP是否在两个IP之间(包括边界)
func IpBetween(from net.IP, to net.IP, test net.IP) bool {
if from == nil || to == nil || test == nil {
glog.Warning("输入的IP为空") // 或者返回错误!?
return false
}
from16 := from.To16()
to16 := to.To16()
test16 := test.To16()
if from16 == nil || to16 == nil || test16 == nil {
glog.Warning("IP未转换为16字节") // 或者返回错误!?
return false
}
if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 {
return true
}
return false
}
和 ip_test.go:
package ip
import (
"net"
"testing"
)
func TestIPBetween(t *testing.T) {
HandleIpBetween(t, "0.0.0.0", "255.255.255.255", "128.128.128.128", true)
HandleIpBetween(t, "0.0.0.0", "128.128.128.128", "255.255.255.255", false)
HandleIpBetween(t, "74.50.153.0", "74.50.153.4", "74.50.153.0", true)
HandleIpBetween(t, "74.50.153.0", "74.50.153.4", "74.50.153.4", true)
HandleIpBetween(t, "74.50.153.0", "74.50.153.4", "74.50.153.5", false)
HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "74.50.153.4", "74.50.153.2", false)
HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", true)
HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:7350", true)
HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", true)
HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:8335", false)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.127", false)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.128", true)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.129", true)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.250", true)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.251", false)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "192.0.2.130", true)
HandleIpBetween(t, "192.0.2.128", "192.0.2.250", "::ffff:192.0.2.130", true)
HandleIpBetween(t, "idonotparse", "192.0.2.250", "::ffff:192.0.2.130", false)
}
func HandleIpBetween(t *testing.T, from string, to string, test string, assert bool) {
res := IpBetween(net.ParseIP(from), net.ParseIP(to), net.ParseIP(test))
if res != assert {
t.Errorf("断言失败(实际结果:%s,期望结果:%s),范围:%s-%s,测试值:%s", res, assert, from, to, test)
}
}
英文:
The generic version for ipv4/ipv6.
ip.go:
package ip
import (
"bytes"
"net"
"github.com/golang/glog"
)
//test to determine if a given ip is between two others (inclusive)
func IpBetween(from net.IP, to net.IP, test net.IP) bool {
if from == nil || to == nil || test == nil {
glog.Warning("An ip input is nil") // or return an error!?
return false
}
from16 := from.To16()
to16 := to.To16()
test16 := test.To16()
if from16 == nil || to16 == nil || test16 == nil {
glog.Warning("An ip did not convert to a 16 byte") // or return an error!?
return false
}
if bytes.Compare(test16, from16) >= 0 && bytes.Compare(test16, to16) <= 0 {
return true
}
return false
}
and ip_test.go:
package ip
import (
"net"
"testing"
)
func TestIPBetween(t *testing.T) {
HandleIpBetween(t, "0.0.0.0", "255.255.255.255", "128.128.128.128", true)
HandleIpBetween(t, "0.0.0.0", "128.128.128.128", "255.255.255.255", false)
HandleIpBetween(t, "74.50.153.0", "74.50.153.4", "74.50.153.0", true)
HandleIpBetween(t, "74.50.153.0", "74.50.153.4", "74.50.153.4", true)
HandleIpBetween(t, "74.50.153.0", "74.50.153.4", "74.50.153.5", false)
HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "74.50.153.4", "74.50.153.2", false)
HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", true)
HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:7350", true)
HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", true)
HandleIpBetween(t, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "2001:0db8:85a3:0000:0000:8a2e:0370:8334", "2001:0db8:85a3:0000:0000:8a2e:0370:8335", false)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.127", false)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.128", true)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.129", true)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.250", true)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "::ffff:192.0.2.251", false)
HandleIpBetween(t, "::ffff:192.0.2.128", "::ffff:192.0.2.250", "192.0.2.130", true)
HandleIpBetween(t, "192.0.2.128", "192.0.2.250", "::ffff:192.0.2.130", true)
HandleIpBetween(t, "idonotparse", "192.0.2.250", "::ffff:192.0.2.130", false)
}
func HandleIpBetween(t *testing.T, from string, to string, test string, assert bool) {
res := IpBetween(net.ParseIP(from), net.ParseIP(to), net.ParseIP(test))
if res != assert {
t.Errorf("Assertion (have: %s should be: %s) failed on range %s-%s with test %s", res, assert, from, to, test)
}
}
答案4
得分: 3
我从这里的一个C#示例中移植了代码:https://stackoverflow.com/a/2138724/1655418
由于某种原因,它比Nick的解决方案快1毫秒。
我的问题是关于“最快”的方法,所以我想发表我的代码,看看社区的想法。
package iptesting
import (
"fmt"
"testing"
"net"
"time"
"bytes"
)
func TestIPRangeTime(t *testing.T) {
lowerBytes := net.ParseIP("216.14.49.184").To4()
upperBytes := net.ParseIP("216.14.49.191").To4()
inputBytes := net.ParseIP("216.14.49.184").To4()
startTime := time.Now()
for i := 0; i < 27000; i++ {
IsInRange(inputBytes, lowerBytes, upperBytes)
}
endTime := time.Now()
fmt.Println("ELAPSED time port: ", endTime.Sub(startTime))
lower := net.ParseIP("216.14.49.184")
upper := net.ParseIP("216.14.49.191")
trial := net.ParseIP("216.14.49.184")
startTime = time.Now()
for i := 0; i < 27000; i++ {
IsInRange2(trial, lower, upper)
}
endTime = time.Now()
fmt.Println("ELAPSED time bytescompare: ", endTime.Sub(startTime))
}
func IsInRange2(trial net.IP, lower net.IP, upper net.IP) bool {
if bytes.Compare(trial, lower) >= 0 && bytes.Compare(trial, upper) <= 0 {
return true
}
return false
}
func IsInRange(ip []byte, lower []byte, upper []byte) bool {
lowerBoundary := true
upperBoundary := true
for i := 0; i < len(lower) && (lowerBoundary || upperBoundary); i++ {
if lowerBoundary && ip[i] < lower[i] || upperBoundary && ip[i] > upper[i] {
return false
}
if ip[i] == lower[i] {
if lowerBoundary {
lowerBoundary = true
} else {
lowerBoundary = false
}
} else {
lowerBoundary = false
}
if ip[i] == upper[i] {
if upperBoundary {
upperBoundary = true
} else {
upperBoundary = false
}
} else {
upperBoundary = false
}
}
return true
}
我的结果:
=== RUN TestIPRangeTime
ELAPSED time port: 1.0001ms
ELAPSED time bytescompare: 2.0001ms
--- PASS: TestIPRangeTime (0.00 seconds)
=== RUN TestIPRangeTime
ELAPSED time port: 1ms
ELAPSED time bytescompare: 2.0002ms
--- PASS: TestIPRangeTime (0.00 seconds)
=== RUN TestIPRangeTime
ELAPSED time port: 1.0001ms
ELAPSED time bytescompare: 2.0001ms
--- PASS: TestIPRangeTime (0.00 seconds)
=== RUN TestIPRangeTime
ELAPSED time port: 1.0001ms
ELAPSED time bytescompare: 2.0001ms
--- PASS: TestIPRangeTime (0.00 seconds)
英文:
I ported over the code from a C# example found here: https://stackoverflow.com/a/2138724/1655418
And for some reason it ends up being 1ms faster than Nick's solution.
My question was for the "fastest" way, so I figured I'd post mine and see what the community thinks.
package iptesting
import (
"fmt"
"testing"
"net"
"time"
"bytes"
)
func TestIPRangeTime(t *testing.T) {
lowerBytes := net.ParseIP("216.14.49.184").To4()
upperBytes := net.ParseIP("216.14.49.191").To4()
inputBytes := net.ParseIP("216.14.49.184").To4()
startTime := time.Now()
for i := 0; i < 27000; i++ {
IsInRange(inputBytes, lowerBytes, upperBytes)
}
endTime := time.Now()
fmt.Println("ELAPSED time port: ", endTime.Sub(startTime))
lower := net.ParseIP("216.14.49.184")
upper := net.ParseIP("216.14.49.191")
trial := net.ParseIP("216.14.49.184")
startTime = time.Now()
for i := 0; i < 27000; i++ {
IsInRange2(trial, lower, upper)
}
endTime = time.Now()
fmt.Println("ELAPSED time bytescompare: ", endTime.Sub(startTime))
}
func IsInRange2(trial net.IP, lower net.IP, upper net.IP) bool {
if bytes.Compare(trial, lower) >= 0 && bytes.Compare(trial, upper) <= 0 {
return true
}
return false
}
func IsInRange(ip []byte, lower []byte, upper []byte) bool {
//fmt.Printf("given ip len: %d\n", len(ip))
lowerBoundary := true
upperBoundary := true
for i := 0; i < len(lower) && (lowerBoundary || upperBoundary); i++ {
if lowerBoundary && ip[i] < lower[i] || upperBoundary && ip[i] > upper[i] {
return false
}
if ip[i] == lower[i] {
if lowerBoundary {
lowerBoundary = true
} else {
lowerBoundary = false
}
//lowerBoundary &= true
} else {
lowerBoundary = false
//lowerBoundary &= false
}
if ip[i] == upper[i] {
//fmt.Printf("matched upper\n")
if upperBoundary {
upperBoundary = true
} else {
upperBoundary = false
}
//upperBoundary &= true
} else {
upperBoundary = false
//upperBoundary &= false
}
}
return true
}
My results:
=== RUN TestIPRangeTime
ELAPSED time port: 1.0001ms
ELAPSED time bytescompare: 2.0001ms
--- PASS: TestIPRangeTime (0.00 seconds)
=== RUN TestIPRangeTime
ELAPSED time port: 1ms
ELAPSED time bytescompare: 2.0002ms
--- PASS: TestIPRangeTime (0.00 seconds)
=== RUN TestIPRangeTime
ELAPSED time port: 1.0001ms
ELAPSED time bytescompare: 2.0001ms
--- PASS: TestIPRangeTime (0.00 seconds)
=== RUN TestIPRangeTime
ELAPSED time port: 1.0001ms
ELAPSED time bytescompare: 2.0001ms
--- PASS: TestIPRangeTime (0.00 seconds)
答案5
得分: 2
func IP2Integer(ip *net.IP) (int64, error) {
ip4 := ip.To4()
if ip4 == nil {
return 0, fmt.Errorf("非法的IP地址: %v", ip)
}
bin := make([]string, len(ip4))
for i, v := range ip4 {
bin[i] = fmt.Sprintf("%08b", v)
}
return strconv.ParseInt(strings.Join(bin, ""), 2, 64)
}
英文:
How about some implementation like inet_pton? The result is easy to be stored.
func IP2Integer(ip *net.IP) (int64, error) {
ip4 := ip.To4()
if ip4 == nil {
return 0, fmt.Errorf("illegal: %v", ip)
}
bin := make([]string, len(ip4))
for i, v := range ip4 {
bin[i] = fmt.Sprintf("%08b", v)
}
return strconv.ParseInt(strings.Join(bin, ""), 2, 64)
}
答案6
得分: 2
Go 1.18
您可以使用新的net/netip
包。该包定义了netip.Addr
类型:
与
net.IP
类型相比,该包的Addr
类型占用更少的内存,是不可变的,并且支持比较(支持==和作为map键)。
您可以使用Compare
方法比较IP地址:
Compare
方法返回比较两个IP地址的整数结果。结果将是:
- 如果
ip == ip2
,则返回0- 如果
ip < ip2
,则返回-1- 如果
ip > ip2
,则返回+1“小于”的定义与
Less
方法相同。
假设您正在处理IPv4地址,一个简单的范围比较可能如下所示:
package main
import (
"fmt"
"net/netip"
)
func main() {
ip1, _ := netip.ParseAddr("216.14.49.184")
ip2, _ := netip.ParseAddr("216.14.49.191")
myIP, _ := netip.ParseAddr("192.168.8.1")
fmt.Println(inRange(ip1, ip2, myIP)) // false
myIP, _ = netip.ParseAddr("216.14.49.185")
fmt.Println(inRange(ip1, ip2, myIP)) // true
}
func inRange(ipLow, ipHigh, ip netip.Addr) bool {
return ipLow.Compare(ip) <= 0 && ipHigh.Compare(ip) > 0
}
注意:在实际的代码中,不要忽略解析IP字符串时的错误。
英文:
Go 1.18
You can use the new package net/netip
. The package defines the type netip.Addr
:
> Compared to the net.IP type, this package's Addr type takes less memory, is immutable, and is comparable (supports == and being a map key).
You can compare IPs with the method Compare
:
> Compare returns an integer comparing two IPs. The result will be:
> - 0 if ip == ip2
> - -1 if ip < ip2
> - +1 if ip > ip2.
>
> The definition of "less than" is the same as the Less method.
Assuming that you're dealing with IPv4 addresses, a simple in-range comparison might look like the following:
package main
import (
"fmt"
"net/netip"
)
func main() {
ip1, _ := netip.ParseAddr("216.14.49.184")
ip2, _ := netip.ParseAddr("216.14.49.191")
myIP, _ := netip.ParseAddr("192.168.8.1")
fmt.Println(inRange(ip1, ip2, myIP)) // false
myIP, _ = netip.ParseAddr("216.14.49.185")
fmt.Println(inRange(ip1, ip2, myIP)) // true
}
func inRange(ipLow, ipHigh, ip netip.Addr) bool {
return ipLow.Compare(ip) <= 0 && ipHigh.Compare(ip) > 0
}
Note: In real-world code don't actually ignore errors from parsing the IP strings.
答案7
得分: 1
ipmatcher.go
type IPMatcher struct {
IP net.IP
SubNet *net.IPNet
}
type IPMatchers []*IPMatcher
func NewIPMatcher(ipStr string) (*IPMatcher, error) {
ip, subNet, err := net.ParseCIDR(ipStr)
if err != nil {
ip = net.ParseIP(ipStr)
if ip == nil {
return nil, errors.New("无效的IP地址:" + ipStr)
}
}
return &IPMatcher{ip, subNet}, nil
}
func (m IPMatcher) Match(ipStr string) bool {
ip := net.ParseIP(ipStr)
if ip == nil {
return false
}
return m.IP.Equal(ip) || (m.SubNet != nil && m.SubNet.Contains(ip))
}
func NewIPMatchers(ips []string) (list IPMatchers, err error) {
for _, ipStr := range ips {
var m *IPMatcher
m, err = NewIPMatcher(ipStr)
if err != nil {
return
}
list = append(list, m)
}
return
}
func IPContains(ipMatchers []*IPMatcher, ip string) bool {
for _, m := range ipMatchers {
if m.Match(ip) {
return true
}
}
return false
}
func (ms IPMatchers) Match(ip string) bool {
return IPContains(ms, ip)
}
ipmatcher_test.go
import "testing"
func TestIPMatcher(t *testing.T) {
a, errA := NewIPMatcher("127.0.0.1")
if errA != nil {
t.Error(errA)
}
if a.IP.String() != "127.0.0.1" || a.SubNet != nil {
t.Error("IP解析错误")
}
b, errB := NewIPMatcher("192.168.1.1/24")
if errB != nil {
t.Error(errB)
}
if b.IP.String() != "192.168.1.1" || b.SubNet == nil {
t.Errorf("IP匹配错误:%s, %v", b.IP.String(), b.SubNet)
}
if !b.Match("192.168.1.1") || !b.Match("192.168.1.2") {
t.Error("IP匹配错误")
}
}
func TestIPMatchers(t *testing.T) {
var WhiteListIPs = []string{"127.0.0.1", "192.168.1.0/24", "10.1.0.0/16"}
M, err := NewIPMatchers(WhiteListIPs)
if err != nil {
t.Error(err)
}
if !M.Match("127.0.0.1") || !M.Match("192.168.1.1") || !M.Match("192.168.1.199") ||
!M.Match("10.1.0.1") || !M.Match("10.1.3.1") {
t.Error("IP匹配错误")
}
if M.Match("127.0.0.2") || M.Match("192.168.2.1") || M.Match("10.2.0.1") {
t.Error("IP匹配错误2")
}
}
你可以在gist链接中查看代码。
英文:
ipmatcher.go
type IPMatcher struct {
IP net.IP
SubNet *net.IPNet
}
type IPMatchers []*IPMatcher
func NewIPMatcher(ipStr string) (*IPMatcher, error) {
ip, subNet, err := net.ParseCIDR(ipStr)
if err != nil {
ip = net.ParseIP(ipStr)
if ip == nil {
return nil, errors.New("invalid IP: "+ipStr)
}
}
return &IPMatcher{ip, subNet}, nil
}
func (m IPMatcher) Match(ipStr string) bool {
ip := net.ParseIP(ipStr)
if ip == nil {
return false
}
return m.IP.Equal(ip) || m.SubNet != nil && m.SubNet.Contains(ip)
}
func NewIPMatchers(ips []string) (list IPMatchers, err error) {
for _, ipStr := range ips {
var m *IPMatcher
m, err = NewIPMatcher(ipStr)
if err != nil {
return
}
list = append(list, m)
}
return
}
func IPContains(ipMatchers []*IPMatcher, ip string) bool {
for _, m := range ipMatchers {
if m.Match(ip) {
return true
}
}
return false
}
func (ms IPMatchers) Match(ip string) bool {
return IPContains(ms, ip)
}
ipmatcher_test.go
import "testing"
func TestIPMatcher(t *testing.T) {
a, errA := NewIPMatcher("127.0.0.1")
if errA != nil {
t.Error(errA)
}
if a.IP.String() != "127.0.0.1" || a.SubNet != nil {
t.Error("ip parse error")
}
b, errB := NewIPMatcher("192.168.1.1/24")
if errB != nil {
t.Error(errB)
}
if b.IP.String() != "192.168.1.1" || b.SubNet == nil {
t.Errorf("ip match error: %s, %v", b.IP.String(), b.SubNet)
}
if !b.Match("192.168.1.1") || !b.Match("192.168.1.2") {
t.Error("ip match error")
}
}
func TestIPMatchers(t *testing.T) {
var WhiteListIPs = []string{"127.0.0.1", "192.168.1.0/24", "10.1.0.0/16"}
M, err := NewIPMatchers(WhiteListIPs)
if err != nil {
t.Error(err)
}
if !M.Match("127.0.0.1") || !M.Match("192.168.1.1") || !M.Match("192.168.1.199") ||
!M.Match("10.1.0.1") || !M.Match("10.1.3.1") {
t.Error("ip match error")
}
if M.Match("127.0.0.2") || M.Match("192.168.2.1") || M.Match("10.2.0.1") {
t.Error("ip match error 2")
}
}
答案8
得分: 0
IPAddress Go库可以以多态的方式快速处理IPv4和IPv6地址。仓库在这里。免责声明:我是项目经理。
import (
"fmt"
"github.com/seancfoley/ipaddress-go/ipaddr"
)
func main() {
isInRange("216.14.49.184", "216.14.49.191", "216.14.49.190")
isInRange("2001:db8:85a3::8a2e:0370:7334",
"2001:db8:85a3::8a00:ff:ffff", "2001:db8:85a3::8a03:a:b")
}
func getAddress(str string) *ipaddr.IPAddress {
return ipaddr.NewIPAddressString(str).GetAddress()
}
func isInRange(range1Str, range2Str, addrStr string) {
range1, range2 := getAddress(range1Str), getAddress(range2Str)
addr := getAddress(addrStr)
rng := range1.SpanWithRange(range2)
fmt.Printf("%v 包含 %v %t\n", rng, addr, rng.Contains(addr))
}
输出:
216.14.49.184 -> 216.14.49.191 包含 216.14.49.190 true
2001:db8:85a3::8a00:ff:ffff -> 2001:db8:85a3::8a2e:370:7334 包含 2001:db8:85a3::8a03:a:b true
英文:
The IPAddress Go library can do this quickly in a polymorphic manner with both IPv4 and IPv6 addresses. Repository here. Disclaimer: I am the project manager.
import (
"fmt"
"github.com/seancfoley/ipaddress-go/ipaddr"
)
func main() {
isInRange("216.14.49.184", "216.14.49.191", "216.14.49.190")
isInRange("2001:db8:85a3::8a2e:0370:7334",
"2001:db8:85a3::8a00:ff:ffff", "2001:db8:85a3::8a03:a:b")
}
func getAddress(str string) *ipaddr.IPAddress {
return ipaddr.NewIPAddressString(str).GetAddress()
}
func isInRange(range1Str, range2Str, addrStr string) {
range1, range2 := getAddress(range1Str), getAddress(range2Str)
addr := getAddress(addrStr)
rng := range1.SpanWithRange(range2)
fmt.Printf("%v contains %v %t\n", rng, addr, rng.Contains(addr))
}
Output:
216.14.49.184 -> 216.14.49.191 contains 216.14.49.190 true
2001:db8:85a3::8a00:ff:ffff -> 2001:db8:85a3::8a2e:370:7334 contains 2001:db8:85a3::8a03:a:b true
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论