Proud member of the Firebagger Lefty blogosphere!

Sunday, March 04, 2007

Saturday Night play - ip_convert-02.pl

For a while I've been wanting a Perl program to demonstrate some basic issues of programming to students. While a bit more advanced than I would like this program does several things -

- it takes user input, in this case a system name, then runs an external program to convert that data into a real ip number
- it parses the number into 4 separate values and stashes each into an array
- it extracts these values from an array and uses a recursive function to convert them from a decimal to a binary number
- it checks that binary number and pads leading zeros to make it 8 bits long
- finally, it appends all the 8 bit numbers together to make a 32 bit sequence that represents the ip number in binary form

ip_convert-02.pl......
(requires dig so probably requires Linux).....
#!/usr/bin/perl -w
#
#
# Author: Michael
# March 3, 2007
#
# A program that demo's conversion of an ip number to
# a binary number
#
# Recursion code from:
# Higher Order Perl
# by Mark Jason Dominus
# 2005, Elsevier, Inc.
#
#
# usage:
# ./ip_convert-02.pl internet_sys_name
# i.e. -- ./ip_convert-02.pl login.swcp.com
#

# stash the number of arguments
# $#ARGV is ARGC in C, C++ land
$argNumber = $#ARGV + 1;

sub usageStatement {
print "\nUsage: ip_convert-02.pl internet_sys_name\n\n";
}

# test for presence of input
if($argNumber != 1) {
&usageStatement();
exit(1);
}

# a recursive function to convert an integer value
# to a binary number
sub binary {
# set input value to $n, keep it local
my ($n) = @_;

# check for base case, if found end recursion
return $n if $n == 0 || $n == 1;

# divide val by 2, set result to $k
my $k = int($n/2);
# divide val by 2, save modulus to $b
my $b = $n % 2;

# recurse $k
my $E = binary($k);

# as recursion unwinds build binary value
return $E . $b;
}

# a function to pad zero's on a binary number so that
# its standardized to 8 bits in length
sub bufferator {
my ($needZeros) = @_ ;

$blank = "";

while ( $needZeros ) {
$blank = $blank . 0;
$needZeros--;
}

return $blank;
}


# convert name to ip number
$ipNumber = `dig +short $ARGV[0]`;
chop($ipNumber);

# slit ip number into an array of numbers minus the .'s
@ipSegments = split(/\./, $ipNumber);

# setup variables to process the array of segments & store results
$i = 0;
$outBinPattern = "";

while ( $i < 4 ) {
# get bit pattern for each 8 bit segment
$binValue = &binary($ipSegments[$i]);

$binLength = length($binValue);

if ( $binLength < 8 ) {
$binLength = 8 - $binLength;

$buffZeros = &bufferator($binLength);

$binValue = $buffZeros . $binValue;
}

$outBinPattern = $outBinPattern . $binValue;

$i++;
}

print "$outBinPattern\n";
exit(0);
..........

No comments: