sorry for the title , i don't know how to say that
i have a questions about this code
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
}
I want to convert an ip address to integer number
you see I have wrote such ugly code
first retrive number from strconv.Atoi then convert it to int64
How to simplify this ?
If you want to parse multiple integers from a string, try the Sscanf function, like this:
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])
}
This construct is heavy but appears more natural if you, as you probably should, were catching the parsing errors.
This being said, the correct solution to that exact problem is to use the existing net.ParseIP
function which builds an IP
func ParseIP(s string) IP
If you must keep your current function prototype, I suggest this :
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])
}
Note that you may add a test on the return of ParseIP (which is nil in case of error)
I don't recommend it, because you would be ignoring errors, but you can write a function to give you the first value:
func first(x int, _ error) int {return x;}
Then use first(strconv.Atoi(p[0]))
in your code.
For the particular code you listed though, I would use the (well tested!) standard library's net.ParseIP() and net.To4() functions:
// 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
}
Note that the above code adds error checking, and also accepts IPv6 formatted v4 addresses "::FFFF:C0A8:0101". Consider whether you really need an int64 type to represent IP addresses, or whether the standard library's net.IP type is good enough for your purposes.