Skip to content

Instantly share code, notes, and snippets.

Last active May 25, 2024 21:43
Show Gist options
  • Save ammario/649d4c0da650162efd404af23e25b86b to your computer and use it in GitHub Desktop.
Save ammario/649d4c0da650162efd404af23e25b86b to your computer and use it in GitHub Desktop.
Golang IP <-> int conversion
func ip2int(ip net.IP) uint32 {
if len(ip) == 16 {
return binary.BigEndian.Uint32(ip[12:16])
return binary.BigEndian.Uint32(ip)
func int2ip(nn uint32) net.IP {
ip := make(net.IP, 4)
binary.BigEndian.PutUint32(ip, nn)
return ip
Copy link

wilrodriguez commented Aug 29, 2023

@ammario Can you explain why you check len(ip) == 16? Wouldn't it return only a quarter of the ipv6 IP?

I honestly can't remember why I did that. The behavior doesn't seem useful, it should probably panic instead. I updated the gist.

I'm surprised no one has mentioned it yet, but this latest change actually breaks the code. The length of both ipv4 and ipv6 addresses in net.IP representation is 16 bytes due the data structure being designed to accommodate both types of addresses. As proof of this point, see the following unit test:

func TestIPRepresentation(t *testing.T) {
	ipv4Str := ""
	ipv6Str := "2001:0db8:85a3:0000:0000:8a2e:0370:7334"

	ipv4 := net.ParseIP(ipv4Str)
	ipv6 := net.ParseIP(ipv6Str)

	t.Logf("IPv4: %s, Length: %d bytes", ipv4, len(ipv4))
	t.Logf("IPv6: %s, Length: %d bytes", ipv6, len(ipv6))

	if len(ipv4) != 16 {
		t.Errorf("IPv4 length is not 16 bytes")

	if len(ipv6) != 16 {
		t.Errorf("IPv6 length is not 16 bytes")

This test results in the following output:

=== RUN   TestIPRepresentation
    ./networking_test.go:72: IPv4:, Length: 16 bytes
    ./networking_test.go:73: IPv6: 2001:db8:85a3::8a2e:370:7334, Length: 16 bytes
--- PASS: TestIPRepresentation (0.00s)
ok      common      0.231s

I've come up with this alternative implementation that depends on net.IP's To4() method, which returns nil for anything that's not a valid v4 IP.

func IPv4toInt(ipv4 net.IP) (uint32, error) {
	ipv4Bytes := ipv4.To4()
	if ipv4Bytes == nil {
		return 0, errors.New("not a valid IPv4 address")
	return binary.BigEndian.Uint32(ipv4Bytes), nil

Note that my implementation does return error, so, if you need a function that only returns a single value, you can always change to a panic like the original function, but I personally like returning an error better.

Copy link

ammario commented Aug 29, 2023

@wilrodriguez I didn't realize how popular this gist was and recklessly updated it. I reverted it back per your message. Thank you!

Copy link

Really helpful!

Copy link

The URL to this gist was produced by Phind-70B - thought you might find that interesting.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment