mirror of
https://github.com/TeaOSLab/EdgeCommon.git
synced 2026-05-17 08:55:34 +08:00
简化IP名单中创建IP操作/支持IP以CIDR方式显示
This commit is contained in:
78
pkg/iputils/cidr.go
Normal file
78
pkg/iputils/cidr.go
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package iputils
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
type CIDR struct {
|
||||
rawIPNet *net.IPNet
|
||||
}
|
||||
|
||||
func ParseCIDR(s string) (*CIDR, error) {
|
||||
_, ipNet, err := net.ParseCIDR(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &CIDR{
|
||||
rawIPNet: ipNet,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (this *CIDR) IsIPv4() bool {
|
||||
return this.rawIPNet.IP.To4() != nil
|
||||
}
|
||||
|
||||
func (this *CIDR) IsIPv6() bool {
|
||||
return this.rawIPNet.IP.To4() == nil
|
||||
}
|
||||
|
||||
func (this *CIDR) From() net.IP {
|
||||
return this.rawIPNet.IP
|
||||
}
|
||||
|
||||
func (this *CIDR) To() net.IP {
|
||||
var start = this.rawIPNet.IP.To4()
|
||||
if start != nil {
|
||||
return bitsOr(bitsAnd(start, this.rawIPNet.Mask), bitsXor(this.rawIPNet.Mask[:4], []byte{0xff, 0xff, 0xff, 0xff}))
|
||||
}
|
||||
|
||||
start = this.rawIPNet.IP.To16()
|
||||
return bitsOr(bitsAnd(start, this.rawIPNet.Mask), bitsXor(this.rawIPNet.Mask[:16], []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}))
|
||||
}
|
||||
|
||||
func (this *CIDR) Contains(ip net.IP) bool {
|
||||
return this.rawIPNet.Contains(ip)
|
||||
}
|
||||
|
||||
func (this *CIDR) String() string {
|
||||
return this.rawIPNet.String()
|
||||
}
|
||||
|
||||
func bitsAnd(x []byte, y []byte) []byte {
|
||||
var l = len(x)
|
||||
var z = make([]byte, l)
|
||||
for i := 0; i < l; i++ {
|
||||
z[i] = x[i] & y[i]
|
||||
}
|
||||
return z
|
||||
}
|
||||
|
||||
func bitsOr(x []byte, y []byte) []byte {
|
||||
var l = len(x)
|
||||
var z = make([]byte, l)
|
||||
for i := 0; i < l; i++ {
|
||||
z[i] = x[i] | y[i]
|
||||
}
|
||||
return z
|
||||
}
|
||||
|
||||
func bitsXor(x []byte, y []byte) []byte {
|
||||
var l = len(x)
|
||||
var z = make([]byte, l)
|
||||
for i := 0; i < l; i++ {
|
||||
z[i] = x[i] ^ y[i]
|
||||
}
|
||||
return z
|
||||
}
|
||||
21
pkg/iputils/cidr_test.go
Normal file
21
pkg/iputils/cidr_test.go
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright 2024 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
|
||||
|
||||
package iputils_test
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/iputils"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseCIDR(t *testing.T) {
|
||||
for _, cidrString := range []string{
|
||||
"192.168.2.100/24",
|
||||
"2607:5300:203:afac::/125",
|
||||
} {
|
||||
cidr, err := iputils.ParseCIDR(cidrString)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(cidr, "=> [", cidr.From(), "-", cidr.To(), "]")
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,10 @@ func IsIPv6(ipString string) bool {
|
||||
return rawIP != nil && rawIP.To4() == nil && rawIP.To16() != nil
|
||||
}
|
||||
|
||||
func IsSameVersion(ip1 string, ip2 string) bool {
|
||||
return IsIPv4(ip1) == IsIPv4(ip2)
|
||||
}
|
||||
|
||||
func IsValid(ipString string) bool {
|
||||
return net.ParseIP(ipString) != nil
|
||||
}
|
||||
|
||||
@@ -229,6 +229,13 @@ func TestCompareIP(t *testing.T) {
|
||||
a.IsTrue(iputils.CompareIP("192.168.1.100", "192.168.1.100") == 0)
|
||||
}
|
||||
|
||||
func TestIsSameVersion(t *testing.T) {
|
||||
var a = assert.NewAssertion(t)
|
||||
a.IsTrue(iputils.IsSameVersion("192.168.1.1", "10.0.0.1"))
|
||||
a.IsTrue(iputils.IsSameVersion("::1", "::5"))
|
||||
a.IsFalse(iputils.IsSameVersion("192.168.1.1", "::5"))
|
||||
}
|
||||
|
||||
func BenchmarkParse(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
iputils.ParseIP("fd00:6868:6868:0:10ac:d056:3bf6:7452")
|
||||
|
||||
Reference in New Issue
Block a user