【Go】IP地址转换:数字与字符串之间高效转换

thinkeridea · · 678 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

转载:[https://blog.thinkeridea.com/201903/go/ip2long.html](https://blog.thinkeridea.com/201903/go/ip2long.html) IP 地址库中 IP 地址的保存格式一般有两种,一种是点分十进制形式(192.168.1.1),另一种是数字形式(3232235777),应用中,经常需要在这两种格式之间做转换。 针对这一个问题我在 [exnet](https://github.com/thinkeridea/go-extend/blob/master/exnet) 扩展包里面实现可两者的转换的快捷方法: - `func IP2Long(ip net.IP) (uint, error)` IP2Long 把 net.IP 转为数值 - `func Long2IP(i uint) (net.IP, error)` Long2IP 把数值转为 net.IP - `func IPString2Long(ip string) (uint, error)` IPString2Long 把 ip 字符串转为数值 - `func Long2IPString(i uint) (string, error)` Long2IPString 把数值转为 ip 字符串 使用示例: ```go package main import ( "fmt" "net" "reflect" "github.com/thinkeridea/go-extend/exnet" ) func main() { ip := "192.168.1.1" n, _ := exnet.IPString2Long(ip) s, _ := exnet.Long2IPString(n) fmt.Println(n, s == ip) Ip1 := net.ParseIP(ip) // 会得到一个16字节的byte,主要为了兼容ipv6 n, _ = exnet.IP2Long(Ip1) Ip2, _ := exnet.Long2IP(n) fmt.Println(n, reflect.DeepEqual(Ip1[12:], Ip2)) } ``` 那么是如何将点分十进制的IP地址转为数字?<br/> IPv4 地址有4个字节,样式如下: <br/> MSB————–LSB <br/> b4 b3 b2 b1 <br/> 每个字节表示的范围: - byte4: 4294967296(1<<32) - byte3: 16777216(1<<24) - byte2: 65536(1<<16) - byte1: 256(1<<8) 通用公式:`b4<<24 | b3<<16 | b2<<16 | b1` <br/> 例如,222.173.108.86 <br/> 转换方法:`222<<24 | 173<<16 | 108<<8 | 86 = 3735907414` <br/> 再例如,1.0.1.1 <br/> 转换方法:`1<<24 | 0<<16 | 1<<8 | 1 = 16777473` <br/> [exnet](https://github.com/thinkeridea/go-extend/blob/master/exnet) 中实现如下: ```go // IPString2Long 把ip字符串转为数值 func IPString2Long(ip string) (uint, error) { b := net.ParseIP(ip).To4() if b == nil { return 0, errors.New("invalid ipv4 format") } return uint(b[3]) | uint(b[2])<<8 | uint(b[1])<<16 | uint(b[0])<<24, nil } ``` 把数值转换为字符串的逻辑翻转过来即可, [exnet](https://github.com/thinkeridea/go-extend/blob/master/exnet) 中实现如下: ```go // Long2IPString 把数值转为ip字符串 func Long2IPString(i uint) (string, error) { if i > math.MaxUint32 { return "", errors.New("beyond the scope of ipv4") } ip := make(net.IP, net.IPv4len) ip[0] = byte(i >> 24) ip[1] = byte(i >> 16) ip[2] = byte(i >> 8) ip[3] = byte(i) return ip.String(), nil } ``` **转载:** **本文作者: 戚银([thinkeridea](https://blog.thinkeridea.com/))** **本文链接: [https://blog.thinkeridea.com/201903/go/ip2long.html](https://blog.thinkeridea.com/201903/go/ip2long.html)** **版权声明: 本博客所有文章除特别声明外,均采用 [CC BY 4.0 CN协议](http://creativecommons.org/licenses/by/4.0/deed.zh) 许可协议。转载请注明出处!**

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

678 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传