IP ranges in the ip2location database are represented by first and last IPs as integers.
I don't know how the conversion from IPs to integers is done, but documentation indicates it is equivalent to this code in PHP:
function ip62long($ipv6) {
return (string) gmp_import(inet_pton($ipv6));
}
If it's a IPv4 (not IPv6), the IP is prepended with '::ffff:'.
I'm trying to import ip2location database into postgres using the column type INET. I would want to convert these integers back to IPs, i.e. revert this routine.
So far I'm using this code:
func StringToIp(in string) net.IP {
var bigint big.Int
bigint.SetString(in, 10)
return bigint.Bytes()
}
That works fine for:
- IPv6 addresses, e.g.
55838750788714571402502155597250560000->2a02:26f7:e5c4:c6c1::
and would work in theory for
- IPv4 addresses (without the
::ffff:prefix), e.g.16909060->1.2.3.4
But it does not work for these case:
- All IPv4 prefixed with
::ffff:, e.g.281470681743360should become0.0.0.0instead of?ffff00000000. - Cases like
0,281470681743359,281474439839744,281474976710656.
I'm looking for a solution to convert all these values back to IPv4 or IPv6 addresses respectively to store them in postgres and look up IPs later on.
The cause of the problem seems to be that
bigint.Bytes()returns less than 16 Bytes if the integer doesn't need it, whilenet.IPexpects either 4 or 16 Bytes.Prepending the
[]byteup with enough zeros results in propernet.IP:Happy to see and accept other, more elegant, ... solutions.