在go語(yǔ)言中實(shí)現(xiàn)IP/CIDR的ip和netmask互轉(zhuǎn)及IP段形式互轉(zhuǎn)及ip是否存在IP/CIDR
Go  /  管理員 發(fā)布于 8個(gè)月前   649
go CIDR的各種轉(zhuǎn)換的實(shí)現(xiàn)示例分享
CIDR,即無(wú)類(lèi)域間路由(Classless Inter-Domain Routing)可以將路由集中起來(lái),
在路由表中更靈活地定義地址,CIDR 標(biāo)記使用一個(gè)斜線(xiàn)分隔符,
后面跟一個(gè)十進(jìn)制數(shù)值表示地址中網(wǎng)絡(luò)部分所占的位數(shù)。
即 如 10.10.1.1/16 這類(lèi)形式的地址。16是子網(wǎng)掩碼
如果要將/16 轉(zhuǎn)換為netmask ip形式
則說(shuō)明二進(jìn)制形式下的ip,前16個(gè)值為1,后面為0,也就是
1111 1111,1111 1111,0000 0000,0000 0000
也就是
255,255,0,0
這樣,它對(duì)應(yīng)的IP段就是
10.10.0.0 - 10.10.255.255
根據(jù)這種方式,判斷一個(gè)ip是否在一個(gè)IP/CIDR 內(nèi),就可以根據(jù)子網(wǎng)掩碼來(lái)計(jì)算
如 10.10.7.6 與 10.10.1.1/16
我們只需判斷 兩者的前16位是否相同,若相同,則在其內(nèi)
10.10.1.1 = 0000 1010.0000 1010.0000 0001.0000 0001
10.10.7.6 = 0000 1010.0000 1010.0000 0101.0000 0100
前16位都是 0000 1010.0000 1010 故可以判斷 10.10.7.6 在 10.10.1.1/16 內(nèi)
代碼示例
IP/CIDR 與 IP netmask 的轉(zhuǎn)換
1.IP/CIDR 轉(zhuǎn)換為 ip與netmask
type IpNetmask struct {
IP string
Netmask string
}
func CIDRToIPNetmase(cidr string) (*IpNetmask, error) {
_, ipNet, err := net.ParseCIDR(cidr)
if err != nil {
return nil, fmt.Errorf("parse CIDR failed: err= %v", err)
}
ones, _ := ipNet.Mask.Size()
mask := net.CIDRMask(ones, 32)
return &IpNetmask{
IP: ipNet.IP.String(),
Netmask: net.IP(mask).String(),
}, nil
}
上文中為了得到perfix 或者說(shuō) 子網(wǎng)掩碼我們做了多次操作,
但是在 go 1.18之后,net/netip包提出了一個(gè)新的方法可以快速得到
netip.ParsePrefix(t)
該方法會(huì)在返回一個(gè)address與int類(lèi)型的perfix
2.netmask 反向轉(zhuǎn)換
func netmaskToSub(mask string) (int, error) {
masks := strings.Split(mask, ".")
if len(masks) != 4 {
return 0, fmt.Errorf("invalid mask, mask: %s", mask)
}
var subs []int
for _, i := range masks {
one, err := strconv.Atoi(i)
if err != nil {
return 0, fmt.Errorf("invalid mask, mask: %s", mask)
}
subs = append(subs, one)
}
ones, _ := net.IPv4Mask(byte(subs[0]), byte(subs[1]), byte(subs[2]), byte(subs[3])).Size()
return ones, nil
}netmask, bits := net.IPv4Mask(255, 255, 255, 248).Size()
CIDR 轉(zhuǎn)換為 地址段
func CIDRtoIPRange(address string) (string, error) {
ip, ipnet, err := net.ParseCIDR(address)
if err != nil {
return "", fmt.Errorf("parse cidr failedL err= %v", err)
}
var ips []string
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
ips = append(ips, ip.String())
}
return fmt.Sprintf("%s-%s", ips[0], ips[len(ips)-1]), nil
}
func inc(ip net.IP) {
for j := len(ip) - 1; j > 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
判斷某IP是否在CIDR內(nèi)
直接通過(guò)net.ParseCIDR方法
得出的 ipNet 有一個(gè)方法就是 contains 判斷輸入ip是否在其內(nèi),在的話(huà)返回true
ipnet.Contains()
以上就是ipCIDR 形式轉(zhuǎn)換為ip ,網(wǎng)關(guān),ip段以及判斷一個(gè)ip是否在一個(gè)ipcidr內(nèi)的方法。
123 在
Clash for Windows作者刪庫(kù)跑路了,github已404中評(píng)論 按理說(shuō)只要你在國(guó)內(nèi),所有的流量進(jìn)出都在監(jiān)控范圍內(nèi),不管你怎么隱藏也沒(méi)用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最簡(jiǎn)單的方法中評(píng)論 好久好久都沒(méi)看友情鏈接申請(qǐng)了,今天剛看,已經(jīng)添加。..博主 在
佛跳墻vpn軟件不會(huì)用?上不了網(wǎng)?佛跳墻vpn常見(jiàn)問(wèn)題以及解決辦法中評(píng)論 @1111老鐵這個(gè)不行了,可以看看近期評(píng)論的其他文章..1111 在
佛跳墻vpn軟件不會(huì)用?上不了網(wǎng)?佛跳墻vpn常見(jiàn)問(wèn)題以及解決辦法中評(píng)論 網(wǎng)站不能打開(kāi),博主百忙中能否發(fā)個(gè)APP下載鏈接,佛跳墻或極光..路人 在
php中使用hyperf框架調(diào)用訊飛星火大模型實(shí)現(xiàn)國(guó)內(nèi)版chatgpt功能示例中評(píng)論 教程很詳細(xì),如果加個(gè)前端chatgpt對(duì)話(huà)頁(yè)面就完美了..
Copyright·? 2019 侯體宗版權(quán)所有·
粵ICP備20027696號(hào)