// Package ip 提供 IP 地址工具。 package ip import ( "net" "strconv" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/net/gipv4" ) // IsValid 判断 s 是否为合法的 IPv4 地址。 func IsValid(s string) bool { return gipv4.Validate(s) } // LocalIP 返回本机第一个非回环 IPv4 地址。 func LocalIP() (string, error) { addrs, err := net.InterfaceAddrs() if err != nil { return "", gerror.Wrap(err, `net.InterfaceAddrs failed`) } for _, addr := range addrs { if ipNet, ok := addr.(*net.IPNet); ok { if ipv4 := ipNet.IP.To4(); ipv4 != nil && !ipv4.IsLoopback() { return ipv4.String(), nil } } } return "", nil } // IsInternal 判断 s 是否为私有/内网 IPv4 地址 // (含私有网段、回环地址、链路本地地址)。 func IsInternal(s string) bool { parsed := net.ParseIP(s) if parsed == nil || parsed.To4() == nil { return false } return parsed.IsPrivate() || parsed.IsLoopback() || parsed.IsLinkLocalUnicast() } // ToLong 将 IPv4 字符串转为 uint32 数值表示 // (大端序,与 inet_aton 一致)。 func ToLong(s string) (uint32, error) { ipv4 := net.ParseIP(s).To4() if ipv4 == nil { return 0, gerror.Newf(`invalid IPv4 address: %s`, s) } return uint32(ipv4[0])<<24 | uint32(ipv4[1])<<16 | uint32(ipv4[2])<<8 | uint32(ipv4[3]), nil } // ToString 将 uint32 的 IPv4 值转为点分十进制字符串。 func ToString(v uint32) string { return strconv.Itoa(int(v>>24)) + "." + strconv.Itoa(int(v>>16&0xFF)) + "." + strconv.Itoa(int(v>>8&0xFF)) + "." + strconv.Itoa(int(v&0xFF)) }