zoukankan      html  css  js  c++  java
  • 【Go】IP地址转换:数字与字符串之间高效转换

    转载:https://blog.thinkeridea.com/201903/go/ip2long.html

    IP 地址库中 IP 地址的保存格式一般有两种,一种是点分十进制形式(192.168.1.1),另一种是数字形式(3232235777),应用中,经常需要在这两种格式之间做转换。

    针对这一个问题我在 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 字符串

    使用示例:

    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地址转为数字?

    IPv4 地址有4个字节,样式如下:

    MSB————–LSB

    b4 b3 b2 b1

    每个字节表示的范围:

    • byte4: 4294967296(1<<32)
    • byte3: 16777216(1<<24)
    • byte2: 65536(1<<16)
    • byte1: 256(1<<8)

    通用公式:b4<<24 | b3<<16 | b2<<16 | b1

    例如,222.173.108.86

    转换方法:222<<24 | 173<<16 | 108<<8 | 86 = 3735907414

    再例如,1.0.1.1

    转换方法:1<<24 | 0<<16 | 1<<8 | 1 = 16777473

    exnet 中实现如下:

    // 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 中实现如下:

    // 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/201903/go/ip2long.html

    版权声明: 本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处!

  • 相关阅读:
    图片中添加文字
    几种经典的滤波算法(转)
    OPENCV初试
    图像处理和图像识别中常用的OpenCV函数
    SIP开发
    【转】opencv老是卡在某一层,
    大电子文件读取成二进制流方案
    C# 调试方法之即时窗口输出
    关于如何解锁你的WP7,以便安装自己开发的程序。
    Windows phone 7 之初体验(一.安装Windows phone 7 sdk)
  • 原文地址:https://www.cnblogs.com/thinkeridea/p/10591766.html
Copyright © 2011-2022 走看看