mirror of
https://github.com/charlienet/go-mixed.git
synced 2025-07-17 16:12:42 +08:00
添加掩码格式
This commit is contained in:
@ -3,9 +3,13 @@ package iprange
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var maskPattern = regexp.MustCompile(`\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b`)
|
||||
|
||||
type IpRange struct {
|
||||
segments []ipSegment
|
||||
}
|
||||
@ -96,7 +100,15 @@ func createSegment(ip string) (ipSegment, error) {
|
||||
}, nil
|
||||
|
||||
case strings.Contains(ip, "/"):
|
||||
if prefix, err := netip.ParsePrefix(ip); err != nil {
|
||||
sec := strings.Split(ip, "/")
|
||||
ip := sec[0]
|
||||
mask := sec[1]
|
||||
|
||||
if maskPattern.MatchString(mask) {
|
||||
mask = strconv.Itoa(MaskToBits(mask))
|
||||
}
|
||||
|
||||
if prefix, err := netip.ParsePrefix(ip + "/" + mask); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return &prefixSegments{prefix: prefix}, nil
|
||||
|
@ -30,6 +30,31 @@ func TestSingleIp(t *testing.T) {
|
||||
assert.False(t, r.Contains("192.168.0.123"))
|
||||
}
|
||||
|
||||
func TestSinglePrefix(t *testing.T) {
|
||||
r, err := NewRange("192.168.2.100/32")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.False(t, r.Contains("192.168.2.56"))
|
||||
assert.True(t, r.Contains("192.168.2.100"))
|
||||
assert.False(t, r.Contains("192.168.2.130"))
|
||||
}
|
||||
|
||||
func TestAllIp(t *testing.T) {
|
||||
r, err := NewRange("0.0.0.0/0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.True(t, r.Contains("192.168.2.100"))
|
||||
assert.True(t, r.Contains("192.3.2.100"))
|
||||
assert.True(t, r.Contains("192.65.2.100"))
|
||||
assert.True(t, r.Contains("172.168.2.100"))
|
||||
assert.True(t, r.Contains("8.8.8.8"))
|
||||
assert.True(t, r.Contains("114.114.114.114"))
|
||||
}
|
||||
|
||||
func TestPrefix(t *testing.T) {
|
||||
r, err := NewRange("192.168.2.0/24")
|
||||
if err != nil {
|
||||
@ -53,6 +78,18 @@ func TestPrefix2(t *testing.T) {
|
||||
assert.False(t, r.Contains("192.168.2.162"))
|
||||
}
|
||||
|
||||
func TestDotMask(t *testing.T) {
|
||||
r, err := NewRange("192.168.15.0/255.255.248.0")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.True(t, r.Contains("192.168.8.10"))
|
||||
assert.True(t, r.Contains("192.168.14.162"))
|
||||
assert.False(t, r.Contains("192.168.3.162"))
|
||||
assert.False(t, r.Contains("192.168.2.162"))
|
||||
}
|
||||
|
||||
func TestRange(t *testing.T) {
|
||||
r, err := NewRange("192.168.2.20-192.168.2.30")
|
||||
if err != nil {
|
||||
|
34
ip_range/mask_bits.go
Normal file
34
ip_range/mask_bits.go
Normal file
@ -0,0 +1,34 @@
|
||||
package iprange
|
||||
|
||||
import "strings"
|
||||
|
||||
var maskBits = map[string]int{
|
||||
"255": 8,
|
||||
"254": 7,
|
||||
"252": 6,
|
||||
"248": 5,
|
||||
"240": 4,
|
||||
"224": 3,
|
||||
"192": 2,
|
||||
"128": 1,
|
||||
"0": 0,
|
||||
}
|
||||
|
||||
func MaskToBits(mask string) int {
|
||||
bits := 0
|
||||
|
||||
secs := strings.Split(mask, ".")
|
||||
if len(secs) != 4 {
|
||||
panic("the mask is incorrect")
|
||||
}
|
||||
|
||||
for _, s := range secs {
|
||||
if v, ok := maskBits[s]; ok {
|
||||
bits += v
|
||||
} else {
|
||||
panic("the mask is incorrect")
|
||||
}
|
||||
}
|
||||
|
||||
return bits
|
||||
}
|
26
ip_range/mask_bits_test.go
Normal file
26
ip_range/mask_bits_test.go
Normal file
@ -0,0 +1,26 @@
|
||||
package iprange
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMaskToBits(t *testing.T) {
|
||||
|
||||
masks := []struct {
|
||||
mask string
|
||||
expect int
|
||||
}{
|
||||
{"255.255.255.0", 24},
|
||||
{"255.255.248.0", 21},
|
||||
{"255.255.192.0", 18},
|
||||
{"255.255.255.192", 26},
|
||||
}
|
||||
|
||||
for _, m := range masks {
|
||||
bits := MaskToBits(m.mask)
|
||||
assert.Equal(t, m.expect, bits, fmt.Sprintf("IP:%s 掩码位数错误。", m.mask))
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user