目录

ip 地址与十进制互转

一、IP地址结构

IPv4地址的两种形态

点分十进制: 192.168.1.1  
32位整型:  3232235777 (0xC0A80101)

转换原理示意图

          192     . 168    . 1      . 1
       11000000 10101000 00000001 00000001  
        |         移位24位        | 移位8位
        ↓                        ↓
3232235777 = (192<<24) | (168<<16) | (1<<8) | 1

二、IP 转 十进制

(一)位运算实现(最高效)

func IPToInt(ip string) uint32 {
    parts := strings.Split(ip, ".")
    var result uint32
    for i := 0; i < 4; i++ {
        num, _ := strconv.Atoi(parts[i])
        result |= uint32(num) << (24 - 8*i)
    }
    return result
}

func IntToIP(n uint32) string {
    return fmt.Sprintf("%d.%d.%d.%d",
        (n>>24)&0xFF, (n>>16)&0xFF, 
        (n>>8)&0xFF, n&0xFF)
}

(二) 标准库 net 包(推荐生产使用)

import "net"

func IPToIntSafe(ip string) (uint32, error) {
    parsed := net.ParseIP(ip).To4()
    if parsed == nil {
        return 0, fmt.Errorf("invalid IPv4 address")
    }
    return binary.BigEndian.Uint32(parsed), nil
}

func IntToIPSafe(n uint32) string {
    ip := make(net.IP, 4)
    binary.BigEndian.PutUint32(ip, n)
    return ip.String()
} 

(三) 大数处理(支持字符串运算)

func BigIPToDecimal(ip string) *big.Int {
    intIP := big.NewInt(0)
    intIP.SetBytes(net.ParseIP(ip).To4())
    return intIP
}

func DecimalToIP(decimal *big.Int) string {
    ip := make(net.IP, 4)
    decimal.FillBytes(ip) // 大端序处理
    return ip.String()
}

三、十进制转 IP

// 十进制 转 IP
/*
(n5>>24):通过将十进制数 n5 的二进制表示向右移动 24 位,我们可以提取出最高位的组件值。
这相当于将 n5 除以 2 的 24 次方并向下取整。
(n5>>16)&0xff:通过将十进制数 n5 的二进制表示向右移动 16 位,
并与 0xff(二进制为 11111111)进行位与操作,我们可以提取出次高位的组件值。
这相当于将 n5 除以 2 的 16 次方并向下取整,然后将结果与 255(二进制为 11111111)进行位与操作
,以确保提取的值在 0-255 的范围内。
*/
func Base10ToIp(base10 int) string {
    // 将十进制数转换回IP地址格式
    // 使用位右移和位与操作提取组件
    ipAddr := fmt.Sprintf("%d", base10>>24) + "." +
        fmt.Sprintf("%d", (base10>>16)&0xff) + "." +
        fmt.Sprintf("%d", (base10>>8)&0xff) + "." +
        fmt.Sprintf("%d", base10&0xff)

    return ipAddr
}