12 "github.com/mikioh/ipaddr"
15 // 从每组地址中分离出起始IP以及结束IP
17 func splitIP(strline
string) []ipaddr
.Prefix
{
19 if strings
.Contains(strline
, "-") && strings
.Contains(strline
, "/") {
20 ss
:= strings
.Split(strline
, "-")
22 iprange1
, iprange2
:= ss
[0], ss
[1]
23 // "1.9.22.0/24-1.9.22.0"
24 if strings
.Contains(iprange1
, "/") && !strings
.Contains(iprange2
, "/") {
25 begin
= iprange1
[:strings
.Index(iprange1
, "/")]
26 if begin
== iprange2
{
29 } else if strings
.Contains(iprange2
, "/") {
30 // 1.9.22.0/24-1.9.22.0/24
31 begin
= iprange1
[:strings
.Index(iprange1
, "/")]
33 // 1.9.22.0-1.9.23.0/24
36 // c, err := ipaddr.Parse(begin + "," + iprange2)
40 // return ipaddr.Aggregate(c.List())
42 if c
, err
:= ipaddr
.Parse(iprange2
); err
== nil {
43 end
= c
.Last().IP
.String()
46 } else if strings
.Contains(strline
, "-") {
47 num_regions
:= strings
.Split(strline
, ".")
48 if len(num_regions
) == 4 {
49 // "xxx.xxx.xxx-xxx.xxx-xxx"
50 for _
, region
:= range num_regions
{
51 if strings
.Contains(region
, "-") {
52 a
:= strings
.Split(region
, "-")
64 // "xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx"
65 a
:= strings
.Split(strline
, "-")
66 begin
, end
= a
[0], a
[1]
67 if 1 <= len(end
) && len(end
) <= 3 {
68 prefix
:= begin
[0:strings
.LastIndex(begin
, ".")]
69 end
= prefix
+ "." + end
72 } else if strings
.HasSuffix(strline
, ".") {
76 } else if strings
.Contains(strline
, "/") {
77 // "xxx.xxx.xxx.xxx/xx"
78 if c
, err
:= ipaddr
.Parse(strline
); err
== nil {
85 if i
:= strings
.LastIndex(strline
, ":"); i
!= -1 {
86 if c
, err
:= ipaddr
.Parse(strline
[:i
]); err
== nil {
94 return ipaddr
.Summarize(net
.ParseIP(begin
), net
.ParseIP(end
))
97 var sepReplacer
= strings
.NewReplacer(`","`, ",", `", "`, ",", "|", ",")
99 func parseIPRangeFile(file
string) (chan string, error
) {
100 f
, err
:= os
.Open(file
)
106 ipranges
:= make([]ipaddr
.Prefix
, 0)
107 scanner
:= bufio
.NewScanner(f
)
109 buf
:= make([]byte, 1024*1024*4)
110 scanner
.Buffer(buf
, 1024*1024*4)
113 line
:= strings
.TrimFunc(scanner
.Text(), func(r rune
) bool {
115 case ',', '|', '"', '\'':
117 case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0:
122 if line
== "" || strings
.HasPrefix(line
, "#") {
126 // 支持 gop 的 "xxx","xxx" 和 goa 的 xxx|xxx 格式
127 if s
:= sepReplacer
.Replace(line
); strings
.Contains(s
, ",") {
128 if c
, err
:= ipaddr
.Parse(s
); err
== nil {
129 ipranges
= append(ipranges
, c
.List()...)
132 ipranges
= append(ipranges
, splitIP(line
)...)
136 /* IP段去重 (此描述对当前算法不适用-2017/09/21)
143 "1.9.22.0-1.9.22.100"
144 "1.9.22.0-1.9.22.255"
155 [1.9.0.0/16 3.3.0.0/16 1.1.1.0/24 203.0.113.0/24 2001:db8::1/128]
158 out
:= make(chan string, 200)
161 if len(ipranges
) > 0 {
162 sort
.Slice(ipranges
, func(i
int, j
int) bool {
163 return strings
.Compare(ipranges
[i
].String(), ipranges
[j
].String()) == -1
165 ipranges
= dedup(ipranges
)
168 rand
.Seed(time
.Now().Unix())
169 perm
:= rand
.Perm(len(ipranges
))
170 for _
, v
:= range perm
{
171 c
:= ipaddr
.NewCursor([]ipaddr
.Prefix
{ipranges
[v
]})
172 for ip
:= c
.First(); ip
!= nil; ip
= c
.Next() {
173 out
<- ip
.IP
.String()
182 func dedup(s
[]ipaddr
.Prefix
) []ipaddr
.Prefix
{
185 for _
, s
:= range s
[1:] {
186 if !t
.Contains(&s
) && !t
.Equal(&s
) {