对不起标题,我不知道怎么说
我对此代码有疑问
func ip2long(ip string) (ret int64) {
p:= strings.Split(ip, ".")
n, _:= strconv.Atoi(p[0])
ret += int64(n)*16777216
n, _= strconv.Atoi(p[1])
ret += int64(n)*65536
n, _= strconv.Atoi(p[2])
ret += int64(n)*256
n, _= strconv.Atoi(p[3])
ret += int64(n)
return
}
我想将IP地址转换为整数
你看我写了这么难看的代码
strconv.Atoi的第一个retrive数字,然后将其转换为int64
如何简化这个?
答案 0 :(得分:7)
如果要从字符串中解析多个整数,请尝试使用Sscanf函数,如下所示:
func main() {
var ip [4] uint32
addr := "192.168.0.1"
_, err := fmt.Sscanf(addr, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])
if err != nil {
fmt.Println(err)
return
}
fmt.Println(ip)
fmt.Println(ip[0]<<24 + ip[1]<<16 + ip[2]<<8 + ip[3])
}
答案 1 :(得分:6)
这个结构很重,但是如果你正如你可能应该捕获解析错误那么看起来更自然。
这就是说,对这个确切问题的正确解决方案是使用现有的net.ParseIP
函数来构建IP
func ParseIP(s string) IP
如果您必须保留当前的功能原型,我建议:
func ip2long(s string) (ret int64) {
bip := ([]byte)(net.ParseIP(s).To4())
return (int64)(bip[0]) * (1 << 24) + (int64)(bip[1]) * (1 << 16) + (int64)(bip[2]) * (1 << 8) + (int64)(bip[3])
}
请注意,您可以在ParseIP的返回上添加一个测试(如果出错,则为nil)
答案 2 :(得分:1)
我不推荐它,因为你会忽略错误,但你可以编写一个函数来给你第一个值:
func first(x int, _ error) int {return x;}
然后在代码中使用first(strconv.Atoi(p[0]))
。
对于您列出的特定代码,我会使用(经过良好测试的!)标准库的net.ParseIP()和net.To4()函数:
// WARNING untested code!!
type InvalidIP string
func (InvalidIP ipStr) Error() string {
return "Invalid IPv4 address: "+ipStr
}
func ip2long(ipStr string) (ret int64, err error) {
var ip net.IP
if ip = net.ParseIP(ipStr); ip == nil {
return 0, InvalidIP(ip)
}
if ip = ip.To4(); ip == nil {
return 0, InvalidIP(ip)
}
for b := range ip {
ret <<= 8
ret += b
}
return ret, nil
}
请注意,上面的代码添加了错误检查,并且还接受IPv6格式的v4地址“:: FFFF:C0A8:0101”。考虑一下你是否真的需要一个int64类型来表示IP地址,或者标准库的net.IP类型是否足够用于你的目的。