#!/usr/bin/perl #author: Chris Sincock #This software is provided as-is and is not guaranteed to be free of defects. Use it only at your own risk. #interactively converts numbers from one base to another #see the usage below for more detail my $goformat="d"; my $giformat=undef; my $val; my $dval; my $true=1; my $false=0; my $sameval=$false; my $of=$goformat; my $if=$giformat; my %widths=(b=>16,d=>0,x=>2,o=>3); if(join(" ",@ARGV) =~ /help/) { &usage; exit 0; } elsif(@ARGV) { if($ARGV[0] eq "-simple") { print hex($ARGV[1])."\n"; exit 0; } for my $l (@ARGV) { &doline($l); } } else { while() { doline($_); } } sub doline() { my $line =shift; $_=$line; s/\s//g; #my $val=undef; exit 0 if(/quit/i); if(/^([oxdb]?)=([oxdb]?)$/i) { if($1) { $if=$giformat=$1; } if($2) { $of=$goformat=$2; } if($2 && !$1) { $sameval=$true; next if(!defined($dval)); } else { next; } } else { $if=$giformat; $of=$goformat; } if($sameval && defined($dval)) { #don't change $val #print STDERR "using same val:$dval\n"; $sameval=$false;#but reset sameval #$val } else { $val=undef; if(/^(.*)=(.)$/) { $of=$2; $_=$1; } next if(!$_); $dval=undef; if(/^[0]?x[=]?([a-f0-9]+)$/i) { $if="x"; $val=$1; } elsif((/^[db][0-9]+/i && $giformat eq "x")) { $if="x"; $val=$_; } elsif(/^o[=]?([0-7]+)$/i) { $if="o"; $val=$1; } elsif(/^b[=]?([01]+)$/i) { $if="b"; $val=$1; } elsif(/^d[=]?([0-9]+)$/i) { $if="d"; $val=$1; } elsif(!defined($giformat)) #no global format, so try guess { #print STDERR "hmmm, trying to guess what you meant by '$_'\n"; if(/^[0-9a-f]*[a-f][0-9a-f]*$/) { $if="x"; } elsif(/^[01]+$/ && (length($_) >=8 || /^0/)) { $if="b"; } elsif(/^([0-9])+$/) { $if="d"; } #never assume octal if($if) { $val=$_; } } else #global format is defined { $val=$_; } #print STDERR "inf=$if, outf=$of\n"; if(!defined($val)) { &usage; } if($if eq "x") { $dval=hex($val); } elsif($if eq "o") { $dval=oct($val); } elsif($if eq "d") { $dval=$val; } elsif($if eq "b") { $dval=0; for my $b (split(//,$val)) { $dval=($dval<<1)+($b eq "1"); } } else { print STDERR "I couldn't figure out what you were giving me\n"; next; } } if(!defined($of)) { print STDERR "I couldn't figure out what you were asking for\n"; next; } if(defined($dval) && $of =~ /^[oxdb]$/i) { my $w=$widths{$of} || ""; printf("$if=$val ==> $of=%0$w$of\n\n",$dval); } } sub usage() { print " usage: [xodb]= specify hex or decimal as default input =[xodb] specify hex, octal, or decimal output (and redisplay last input) [xodb]=[xodb] specifies both default input and output specify a query like: informat=number=outformat where format and outformat can be 0x, x, d, o, b =outformat can be omitted in which case the last one selected will be used informat= can be omitted and a reasonable guess will be made the = at the end of the informat can usually be omitted for example o77 and o=77 are equivalent. the exceptions are numbers starting with d or b for example: d11 will be interpreted as decimal 11 unless x= has been set and b11 will be interpreted as binary 11 unless x= has been set also, the number can be omitted to set both defaults like this example: o=b which says that from now on to assume octal input and binary output. the idea is that you should be able to specify what you are working with, how you want to see it, and then paste or type in values to be converted. examples: ######### =x #user selects hex output as default from now on 128 #user enters a decimal number d=128 ==> x=80 #answer is 128 decimal is 80 hex =d #user changes to use decimal output as default d=128 ==> d=128 #last answer is redisplayed in new output format 1a #user enters a hex number x=1a ==> d=26 #answer is 1a hex is 26 decimal 78=x #user asks for 77 decimal in hex format d=78 ==> x=4e #answer is 4e hex x78 #user asks for hex 78 in dec format (from earlier =d) x=78 ==> d=120 #answer is 120 decimal o77 #user enters octal 77 o=77 ==> d=63 #answer is 73 decimal x99=b #user enters hex 99 and asks for binary output x=99 ==> b=0000000010011001 #answer in binary (least sig bits at right) "; }