patterngoMinor
Go string formatting
Viewed 0 times
formattingstringstackoverflow
Problem
I'm very new to Go, and am trying to get some experience by re-writing some of my Python code in Go. Below is a function that takes an IP address (ipv4) in integer form and returns the string version. From
I'm not only curious if there is a more straightforward or concise way to do this with Go, but am very curious if there is a way to use the
Something similar to:
572779703 to 34.35.236.183 for example.func int2ip(num int) (string) {
result := [4]int{}
for i, n := range []uint{24, 16, 8, 0} {
result[i] = (num >> n) & 255
}
return fmt.Sprintf("%d.%d.%d.%d", result[0], result[1], result[2], result[3])
}I'm not only curious if there is a more straightforward or concise way to do this with Go, but am very curious if there is a way to use the
[]result array in Sprintf() without having to type out every index.Something similar to:
fmt.Sprintf("%d.%d.%d.%d", result)Solution
The proper way of doing this is to use the tools the language already gave you.
IPv4 usually are stored as big endian numbers, and Go already have an
playground
//edit adding more details following @Schism's advice
Using Sprintf is usually fine and they worked on optimizing it fairly well, if you want to squeeze every drop of performance out of it, you could use a more "buffered" alternative like :
IPv4 usually are stored as big endian numbers, and Go already have an
IP type:func int2ip(num int) net.IP {
var b [4]byte
binary.BigEndian.PutUint32(b[:], uint32(num))
return net.IPv4(b[0], b[1], b[2], b[3])
}
//or if you don't care about returning net.IP
func int2ipstr(num int) string {
var b [4]byte
binary.BigEndian.PutUint32(b[:], uint32(num))
return fmt.Sprintf("%d.%d.%d.%d", b[0], b[1], b[2], b[3])
}playground
//edit adding more details following @Schism's advice
Using Sprintf is usually fine and they worked on optimizing it fairly well, if you want to squeeze every drop of performance out of it, you could use a more "buffered" alternative like :
func int2ipb(num int) string {
b, buf := [4]byte{}, make([]byte, 0, 15) //15 = max number of bytes in an ip
binary.BigEndian.PutUint32(b[:], uint32(num))
for _, n := range b {
buf = append(buf, '.')
buf = append(buf, strconv.Itoa(int(n))[:]...)
}
return string(buf[1:])
}Code Snippets
func int2ip(num int) net.IP {
var b [4]byte
binary.BigEndian.PutUint32(b[:], uint32(num))
return net.IPv4(b[0], b[1], b[2], b[3])
}
//or if you don't care about returning net.IP
func int2ipstr(num int) string {
var b [4]byte
binary.BigEndian.PutUint32(b[:], uint32(num))
return fmt.Sprintf("%d.%d.%d.%d", b[0], b[1], b[2], b[3])
}func int2ipb(num int) string {
b, buf := [4]byte{}, make([]byte, 0, 15) //15 = max number of bytes in an ip
binary.BigEndian.PutUint32(b[:], uint32(num))
for _, n := range b {
buf = append(buf, '.')
buf = append(buf, strconv.Itoa(int(n))[:]...)
}
return string(buf[1:])
}Context
StackExchange Code Review Q#60399, answer score: 2
Revisions (0)
No revisions yet.