1

I have a variable in perl cgi, that stores a hex value.

My requirement is to find if this variable contains an ipv4 address or an ipv6 address.

And as per this, I need to call

inet_ntop(AF_INET, $ip); #ipv4

Or

inet_ntop(AF_INET6, $ip); #ipv6

The solution that came up in my mind is to calculate the number of bits to find out if it is an ipv4 address or an ipv6 address.

For example,

If the hex value is 0xc0a84607 (ipv4 address), the number of bits will be 32

And if the hex value is 0xfe800000000000000cd86d653903694b (ipv6 address), the number of bits will be 128.

Please note that the number of bits should be 128 even in case of hex value corresponding to valid IPv6 addresses like ::3.

I was not able to find any library function that gives me the number of bits. Is there any way to accomplish this?

Thanks in advance.

Athul Sukumaran
  • 360
  • 4
  • 16
  • [Bit::Fast](https://metacpan.org/pod/Bit::Fast) has popcount for 32-bit and 64-bit integers, but I think you're going to want a better approach than what you propose for your problem. – Shawn Nov 24 '20 at 17:53
  • Maybe enough using [`length` core function](https://perldoc.perl.org/functions/length) – Miguel Prz Nov 24 '20 at 18:55
  • You say the number `3` should return `128` because it could mean `::3`, but it could also mean `0.0.0.3`. How did you decide it should be `128` for `3`? – ikegami Nov 26 '20 at 04:48

1 Answers1

1
#!/usr/bin/env perl

use v5.24;
use warnings;
use bignum;     # needed to deal with 0xfe800000000000000cd86d653903694b
use experimental 'signatures';
use POSIX qw(ceil);

sub minbits($n)
{
    return ceil(log($n)/log(2));
}

say minbits(hex("0xc0a84607"));                             #  32
say minbits(hex("0xfe800000000000000cd86d653903694b"));     # 128
mscha
  • 6,509
  • 3
  • 24
  • 40