Dear All,

Can any one tell me how to convert the IP address from dec to hex decimal.

For Ex:

255.102.25.02/32 should look like FF661902 since its 32 bit

255.102.25.02/31 should derive two values FF661902, FF661903 since its 31 bit

Recommended Answers

All 9 Replies

I don't understand the 31 versus 32 bit distinction well enough to give a complete solution but here is a partial one:

#!/usr/bin/perl
use strict;
use warnings;

my @examples = ('255.102.25.02/32', '255.102.25.02/31');
my @results;

foreach my $example(@examples){
    my ($ip, $bits) = split /\//, $example;
    if ($bits == 32){
        push @results, convert32($ip);
    }
    else {
        push @results, convert31($ip);
    }
}

my $i = 0;
foreach(@examples){
    print "$_ ==> $results[$i++]\n";
}

sub convert32{
    my $ip = shift;
    my @octets = split /\./, $ip;
    my $result;
    foreach (@octets){
        $result .= sprintf("%02X", $_);
    }
    return $result;
}

sub convert31{
    #This subroutine needs more work
    my $ip = shift;
    #I don't know the rules for converting a 31-bit ip
    return "I don't know how to convert $ip/31";
}

I don't understand the 31 versus 32 bit distinction well enough to give a complete solution but here is a partial one:

#!/usr/bin/perl
use strict;
use warnings;

my @examples = ('255.102.25.02/32', '255.102.25.02/31');
my @results;

foreach my $example(@examples){
    my ($ip, $bits) = split /\//, $example;
    if ($bits == 32){
        push @results, convert32($ip);
    }
    else {
        push @results, convert31($ip);
    }
}

my $i = 0;
foreach(@examples){
    print "$_ ==> $results[$i++]\n";
}

sub convert32{
    my $ip = shift;
    my @octets = split /\./, $ip;
    my $result;
    foreach (@octets){
        $result .= sprintf("%02X", $_);
    }
    return $result;
}

sub convert31{
    #This subroutine needs more work
    my $ip = shift;
    #I don't know the rules for converting a 31-bit ip
    return "I don't know how to convert $ip/31";
}

Thank you very much :) but can some one tell me how to proceed with 31 bit convertion.

Thank you very much :) but can some one tell me how to proceed with 31 bit convertion.

Can you tell us the rule for generating two hex values for the 31-bit conversion? Your example looks like the first value for the 31-bit conversion is identical to the result of the 32-bit conversion, and the second value is created by adding one to the first value. Is that the rule?

Can you tell us the rule for generating two hex values for the 31-bit conversion? Your example looks like the first value for the 31-bit conversion is identical to the result of the 32-bit conversion, and the second value is created by adding one to the first value. Is that the rule?

Assuming the above rule for 31-bit conversion, the following should give the results given in your example:

#!/usr/bin/perl
use strict;
use warnings;

my @examples = ('255.102.25.02/32', '255.102.25.02/31');
my @results;

foreach my $example(@examples){
    my ($ip, $bits) = split /\//, $example;
    if ($bits == 32){
        push @results, convert32($ip);
    }
    else {
        push @results, convert31($ip);
    }
}

my $i = 0;
foreach(@examples){
    my $string = join(', ', @{$results[$i++]});
    print "$_ ==> $string\n";
}

sub convert32{
    my $ip = shift;
    my @octets = split /\./, $ip;
    my $result;
    my @arr;
    foreach (@octets){
        $result .= sprintf("%02X", $_);
    }
    push @arr, $result;
    return \@arr;#Reference to array
}

sub convert31{
    my $ip = shift;
    my @arr;
    #The first value
    my $firstvalue = convert32($ip);
    push @arr, @$firstvalue;
    
    #The second value
    my $val2 = sprintf('%08X', hex($$firstvalue[0]) + 1);
    push @arr, $val2;
    return \@arr;#Reference to array;
}

Hi here is the rule for 31 bit convertion.

I/P - 255.102.25.02/32
O/P - FF661902 (We got this output because each digit will carry 4 bits and hence for 8 digit its 32 bit.)

I/P - 255.102.25.02/31
O/P - FF661902, FF661903
In order to convert this, it will first search for the near by integer that is 32 bit.
So now it will take first 7 digit FF66190 (which forms 28-bit)
In order to form 32 bit number it has to add one more digit.
Here till 001 its 31 bit. Since there are 2 digit with 001 combination it will take both the value to form the output.
2 - 0010
3 - 0011


Please find the another example below:
I/P : 131.166.254.0/29
O/P : 83A6FE00,83A6FE01,83A6FE02,83A6FE03,83A6FE04,83A6FE05,83A6FE06,83A6FE07

Thanks for the explanation. I tried today to come up with a solution but so far this stumps me. Does anyone else know how to do this?

How about converting the 32-bit hex string to a string of ones and zeros representing the value converted to binary? Then you can keep the first n number of bits and concatenate with the possible ending strings of bits to get one or more 32-bit binary strings which you can convert to hex strings.

#!/usr/bin/perl
use strict;
use warnings;

my @examples = ('255.102.25.02/32',
                '255.102.25.02/31',
                '131.166.254.0/29');
my @results;

foreach my $example(@examples){
    my ($ip, $bits) = split /\//, $example;
    push @results, ip2hex($ip, $bits);
}

my $i = 0;
foreach(@examples){
    my $string = join(', ', @{$results[$i++]});
    print "$_ ==> $string\n";
}

sub convert32{
    my $ip = shift;
    my @octets = split /\./, $ip;
    my $result;
    my @arr;
    foreach (@octets){
        $result .= sprintf("%02X", $_);
    }
    return $result;
}

sub ip2hex{
    my ($ip, $n) = @_;
    my @arrbin;
    my @arrhex;
    #The nearest 32-bit string
    my $str32 = convert32($ip);
    if ($n == 32){
        return [$str32];
    }
    my $onesandzeros = dec2bin(hex($str32));
    my $keepbits = substr($onesandzeros, 0, $n);
    my @varybits;
    my $len = 32 - $n;
    my $start = '0' x ($len);
    my $end = '1' x ($len);
    push @varybits, sprintf("%0${len}s", dec2bin($_)) foreach (bin2dec($start) .. bin2dec($end));
    push @arrbin, $keepbits . $_ foreach (@varybits);
    push @arrhex, convert32(bin2dec($_)) foreach (@arrbin);
    return \@arrhex;#Reference to array;
}

sub dec2bin {
    #see http://docstore.mik.ua/orelly/perl/cookbook/ch02_05.htm
    my $str = unpack("B32", pack("N", shift));
    $str =~ s/^0+(?=\d)//; # otherwise you'll get leading zeros
    return $str;
}

sub bin2dec {
    return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}

This gives the following output:

255.102.25.02/32 ==> FF661902
255.102.25.02/31 ==> FF661902, FF661903
131.166.254.0/29 ==> 83A6FE00, 83A6FE01, 83A6FE02, 83A6FE03, 83A6FE04, 83A6FE05, 83A6FE06, 83A6FE07

How about this one?

#!perl -w
while(<>)
{
chomp;
s!/(\d{1,3})!!;
@h = split /\./;
for(@h){$_=sprintf "%x",$_;}
$a = join "",@h;
$a = hex $a;
$a >>= (32-$1);
$a <<= (32-$1);
printf "Possible addresses are ranging from: %08x to %08x\n",$a,$a+2**(32-$1)-1;
}
commented: Shorter than mine and it works. +8
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.