func ip2int(ip net.IP) uint32 { | |
if len(ip) == 16 { | |
panic("no sane way to convert ipv6 into uint32") | |
} | |
return binary.BigEndian.Uint32(ip) | |
} | |
func int2ip(nn uint32) net.IP { | |
ip := make(net.IP, 4) | |
binary.BigEndian.PutUint32(ip, nn) | |
return ip | |
} |
There's no native 16 byte integer in Go, so unfortunately it wouldn't make too much sense. You could replace the 4
with 16
and use math/big.Int
instead of ints if you are committed.
Yeah, i got it. I put it here for future adventurers of GO
func ipv6ToInt(IPv6Addr net.IP) *big.Int {
IPv6Int := big.NewInt(0)
IPv6Int.SetBytes(IPv6Addr)
return IPv6Int
}
func IntToIpv6(intipv6 *big.Int) net.IP {
ip := intipv6.Bytes()
var a net.IP = ip
return a
}
Regards
Yeah, i got it. I put it here for future adventurers of GO
func ipv6ToInt(IPv6Addr net.IP) *big.Int { IPv6Int := big.NewInt(0) IPv6Int.SetBytes(IPv6Addr) return IPv6Int }
func IntToIpv6(intipv6 *big.Int) net.IP { ip := intipv6.Bytes() var a net.IP = ip return a }
Regards
For the second conversion, could you not just do:
func IntToIpv6(intipv6 *big.Int) net.IP {
return net.IP(intipv6.Bytes())
}
or even
func IntToIpv6(intipv6 *big.Int) net.IP {
return intipv6.Bytes()
}
In my Active Directory, the IP 173.208.122.131 converts to this -1378846077 when I use the above function ip2int it converts to this 2916121219
how can I convert these IP'sto Active Directory IP bytes
if you want convert ip address represents srting type (often case when you make web services), you have string ip <->int converting. The converting method above makes allocations and overhead in stdlib net\ip.go line 49,50
p := make(IP, IPv6len) copy(p, v4InV6Prefix)
You may copy some funcs from stdlib packet and a little modify they such as
https://play.golang.org/p/z_KMQrEsYqP
This func ParseIPv4(s string) int makes int from string without overhead in allocations
Yeah, i got it. I put it here for future adventurers of GO
func ipv6ToInt(IPv6Addr net.IP) *big.Int { IPv6Int := big.NewInt(0) IPv6Int.SetBytes(IPv6Addr) return IPv6Int }
func IntToIpv6(intipv6 *big.Int) net.IP { ip := intipv6.Bytes() var a net.IP = ip return a }
Regards
Hi @srPuebla, are you using these 2 functions, especially for IntToIpv6
? I think there is a bug for it, you can try the case:
- convert
::1
to bigInt byipv6ToInt
- reverse the conversion by using
IntToIpv6
After above steps, you may find the problem. Besides, there should be a new solution to handle it.
@zhlsunshine The reason is the net.IP accepts an array of byte. When converting back from BigInt, it needs to fill the prefix with 0s up to the length of the IP or it can't recognize the IP. See this example: https://pkg.go.dev/net#IP
praserx has a solution for this: https://github.com/praserx/ipconv/blob/master/ipconv.go
Or just write a loop to determine the IP type (v4 or v6), then fill out the prefix slice.
@ammario Can you explain why you check len(ip) == 16
? Wouldn't it return only a quarter of the ipv6 IP?
@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.
Could you provide 2 similar functions for IPV6?
Thanks!