1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
use strict;
use bigint;
use Getopt::Long;
use constant {
DEBUG => 0,
HELP => 0,
PROGRAM => 'vincoder',
VERSION => 'v0.1.1',
};
my %config;
# handle command line options
&GetOptions(
'help|?|h' => \$config{'help'},
'vin|v=s' => \$config{'VIN_input'},
'bin|b=s' => \$config{'BIN_input'},
'debug|d' => \$config{'debug'},
'version' => \$config{'displayVersion'},
);
# Display version or usage information if requested (or implicitly)
&usage if ($config{'help'});
&usage unless (defined($config{'VIN_input'}) || defined($config{'BIN_input'}));
&version if (defined($config{'displayVersion'}));
my (%charArr, %numArr);
# generate character array
for my $i (0..9, "A".."Z") { $charArr{$i} = keys(%charArr) }
# handle VIN -> binary/hexadecimal
if (defined($config{'VIN_input'})) {
die ("Wrong length to be text VIN.\n") unless (length($config{'VIN_input'}) == 17);
die ("Improper characters in VIN.\n") unless ($config{'VIN_input'} =~ /^[0-9A-HJ-NPR-Z]{17}$/i);
print (uc($config{'VIN_input'}) . ' -> ' . &formathex(uc(&VINtoHex($config{'VIN_input'})->as_hex)) . "\n");
}
# handle binary/hexadecimal -> VIN
if (defined($config{'BIN_input'})) {
$config{'BIN_input'} =~ s/\s+//g;
die ("Wrong length to be decimal or hexadecimal VIN.\n") unless (length($config{'BIN_input'}) == 13 || 26);
die ("Improper hexadecimal characters.\n") unless ($config{'BIN_input'} =~ /^[0-9A-F]{26}$/i);
print (&formathex(uc($config{'BIN_input'})) . ' -> ' . &hexToVIN('0x' . $config{'BIN_input'}) . "\n");
}
#----------------------------
# SUBROUTINES |
#----------------------------
# simple usage/syntax
sub usage {
print("\nUsage: " . PROGRAM . " --vin={VIN} --bin={BINARY/HEX} --help --version\n\n");
exit (1);
}
# display version, then exit.
sub version {
print (PROGRAM . ' ' . VERSION . "\n");
exit (0);
}
# simple debug function
sub debug ($) {
print (@_) if $config{'debug'};
}
# Make the hex output more readable
sub formathex($) {
my $hexStr = shift();
my $formatted;
foreach (my $key = 0; $key < length($hexStr); $key++) {
$formatted .= (substr($hexStr, $key, 2) . ' ') unless ($key % 2);
}
$formatted =~ s/^0x//ig;
return ($formatted);
}
sub VINtoHex ($) {
my $VIN = shift();
my $hex;
for (my $i = 1; $i <= length($VIN); $i++) {
$hex += $charArr{substr(uc($VIN), -$i, 1)} * 0x40**($i-1);
}
return ($hex);
}
sub hexToVIN ($) {
my $hex = shift();
my $VIN;
my %numArr = reverse(%charArr);
for (my $i = 0x10; $i >= 0; $i--) {
my $j = $hex / 0x40**($i);
$hex -= $j * 0x40**($i);
$VIN .= ($numArr{$j});
}
return (uc($VIN));
}
~ ]$ chmod 755 vincoder
~ ]$ ./vincoder -b=202dc34e24310404b8c9203048
20 2D C3 4E 24 31 04 04 B8 C9 20 30 48 -> WBSDE93441BZ98318
~ ]$ ./vincoder -v=WBSDE93441BZ98318
WBSDE93441BZ98318 -> 20 2D C3 4E 24 31 04 04 B8 C9 20 30 48
|