#!/usr/bin/perl

####################################
#  A simple perl script to quiz
#  you on multiple types of conversions.
#
#
# Aaron Burgemeister ab@novell.com dajoker@gmail.com
# Idea and initial build courtesy Joshua Dustin jdustin@gmail.com
#####################################

use warnings;
use strict;


#Methods
sub getChars()
{
  my(@chars) = (
    {'dec' => '0', 'hex' => '0x00', 'oct' => '000', 'char' => 'NUL', 'detail' => '(null)'}, 
    {'dec' => '1', 'hex' => '0x01', 'oct' => '001', 'char' => 'SOH', 'detail' => '(start of heading)'}, 
    {'dec' => '2', 'hex' => '0x02', 'oct' => '002', 'char' => 'STX', 'detail' => '(start of text)'}, 
    {'dec' => '3', 'hex' => '0x03', 'oct' => '003', 'char' => 'ETX', 'detail' => '(end of text)'}, 
    {'dec' => '4', 'hex' => '0x04', 'oct' => '004', 'char' => 'EOT', 'detail' => '(end of transmission)'}, 
    {'dec' => '5', 'hex' => '0x05', 'oct' => '005', 'char' => 'ENQ', 'detail' => '(enquiry)'}, 
    {'dec' => '6', 'hex' => '0x06', 'oct' => '006', 'char' => 'ACK', 'detail' => '(acknowledge)'}, 
    {'dec' => '7', 'hex' => '0x07', 'oct' => '007', 'char' => 'BEL', 'detail' => '(bell)'}, 
    {'dec' => '8', 'hex' => '0x08', 'oct' => '010', 'char' => 'BS', 'detail' => '(backspace)'}, 
    {'dec' => '9', 'hex' => '0x09', 'oct' => '011', 'char' => 'TAB', 'detail' => '(horizontal tab)'}, 
    {'dec' => '10', 'hex' => '0x0a', 'oct' => '012', 'char' => 'LF', 'detail' => '(NL line feed, new line)'}, 
    {'dec' => '11', 'hex' => '0x0b', 'oct' => '013', 'char' => 'VT', 'detail' => '(vertical tab)'}, 
    {'dec' => '12', 'hex' => '0x0c', 'oct' => '014', 'char' => 'FF', 'detail' => '(NP form feed, new page)'}, 
    {'dec' => '13', 'hex' => '0x0d', 'oct' => '015', 'char' => 'CR', 'detail' => '(carriage return)'}, 
    {'dec' => '14', 'hex' => '0x0e', 'oct' => '016', 'char' => 'SO', 'detail' => '(shift out)'}, 
    {'dec' => '15', 'hex' => '0x0f', 'oct' => '017', 'char' => 'SI', 'detail' => '(shift in)'}, 
    {'dec' => '16', 'hex' => '0x10', 'oct' => '020', 'char' => 'DLE', 'detail' => '(data link escape)'}, 
    {'dec' => '17', 'hex' => '0x11', 'oct' => '021', 'char' => 'DC1', 'detail' => '(device control 1)'}, 
    {'dec' => '18', 'hex' => '0x12', 'oct' => '022', 'char' => 'DC2', 'detail' => '(device control 2)'}, 
    {'dec' => '19', 'hex' => '0x13', 'oct' => '023', 'char' => 'DC3', 'detail' => '(device control 3)'}, 
    {'dec' => '20', 'hex' => '0x14', 'oct' => '024', 'char' => 'DC4', 'detail' => '(device control 4)'}, 
    {'dec' => '21', 'hex' => '0x15', 'oct' => '025', 'char' => 'NAK', 'detail' => '(negative acknowledge)'}, 
    {'dec' => '22', 'hex' => '0x16', 'oct' => '026', 'char' => 'SYN', 'detail' => '(synchronous idle)'}, 
    {'dec' => '23', 'hex' => '0x17', 'oct' => '027', 'char' => 'ETB', 'detail' => '(end of trans. block)'}, 
    {'dec' => '24', 'hex' => '0x18', 'oct' => '030', 'char' => 'CAN', 'detail' => '(cancel)'}, 
    {'dec' => '25', 'hex' => '0x19', 'oct' => '031', 'char' => 'EM', 'detail' => '(end of medium)'}, 
    {'dec' => '26', 'hex' => '0x1a', 'oct' => '032', 'char' => 'SUB', 'detail' => '(substitute)'}, 
    {'dec' => '27', 'hex' => '0x1b', 'oct' => '033', 'char' => 'ESC', 'detail' => '(escape)'}, 
    {'dec' => '28', 'hex' => '0x1c', 'oct' => '034', 'char' => 'FS', 'detail' => '(file separator)'}, 
    {'dec' => '29', 'hex' => '0x1d', 'oct' => '035', 'char' => 'GS', 'detail' => '(group separator)'}, 
    {'dec' => '30', 'hex' => '0x1e', 'oct' => '036', 'char' => 'RS', 'detail' => '(record separator)'}, 
    {'dec' => '31', 'hex' => '0x1f', 'oct' => '037', 'char' => 'US', 'detail' => '(unit separator)'}, 
    {'dec' => '32', 'hex' => '0x20', 'oct' => '040', 'char' => 'Space', 'detail' => 'Space'}, 
    {'dec' => '33', 'hex' => '0x21', 'oct' => '041', 'char' => '!', 'detail' => '!'}, 
    {'dec' => '34', 'hex' => '0x22', 'oct' => '042', 'char' => '“', 'detail' => '“'}, 
    {'dec' => '35', 'hex' => '0x23', 'oct' => '043', 'char' => '#', 'detail' => '#'}, 
    {'dec' => '36', 'hex' => '0x24', 'oct' => '044', 'char' => '$', 'detail' => '$'}, 
    {'dec' => '37', 'hex' => '0x25', 'oct' => '045', 'char' => '%', 'detail' => '%'}, 
    {'dec' => '38', 'hex' => '0x26', 'oct' => '046', 'char' => '&', 'detail' => '&'}, 
    {'dec' => '39', 'hex' => '0x27', 'oct' => '047', 'char' => '\'', 'detail' => '\''}, 
    {'dec' => '40', 'hex' => '0x28', 'oct' => '050', 'char' => '(', 'detail' => '('}, 
    {'dec' => '41', 'hex' => '0x29', 'oct' => '051', 'char' => ')', 'detail' => ')'}, 
    {'dec' => '42', 'hex' => '0x2A', 'oct' => '052', 'char' => '*', 'detail' => '*'}, 
    {'dec' => '43', 'hex' => '0x2B', 'oct' => '053', 'char' => '+', 'detail' => '+'}, 
    {'dec' => '44', 'hex' => '0x2C', 'oct' => '054', 'char' => ',', 'detail' => ','}, 
    {'dec' => '45', 'hex' => '0x2D', 'oct' => '055', 'char' => '-', 'detail' => '-'}, 
    {'dec' => '46', 'hex' => '0x2E', 'oct' => '056', 'char' => '.', 'detail' => '.'}, 
    {'dec' => '47', 'hex' => '0x2F', 'oct' => '057', 'char' => '/', 'detail' => '/'}, 
    {'dec' => '48', 'hex' => '0x30', 'oct' => '060', 'char' => '0', 'detail' => '0'}, 
    {'dec' => '49', 'hex' => '0x31', 'oct' => '061', 'char' => '1', 'detail' => '1'}, 
    {'dec' => '50', 'hex' => '0x32', 'oct' => '062', 'char' => '2', 'detail' => '2'}, 
    {'dec' => '51', 'hex' => '0x33', 'oct' => '063', 'char' => '3', 'detail' => '3'}, 
    {'dec' => '52', 'hex' => '0x34', 'oct' => '064', 'char' => '4', 'detail' => '4'}, 
    {'dec' => '53', 'hex' => '0x35', 'oct' => '065', 'char' => '5', 'detail' => '5'}, 
    {'dec' => '54', 'hex' => '0x36', 'oct' => '066', 'char' => '6', 'detail' => '6'}, 
    {'dec' => '55', 'hex' => '0x37', 'oct' => '067', 'char' => '7', 'detail' => '7'}, 
    {'dec' => '56', 'hex' => '0x38', 'oct' => '070', 'char' => '8', 'detail' => '8'}, 
    {'dec' => '57', 'hex' => '0x39', 'oct' => '071', 'char' => '9', 'detail' => '9'}, 
    {'dec' => '58', 'hex' => '0x3A', 'oct' => '072', 'char' => ':', 'detail' => ':'}, 
    {'dec' => '59', 'hex' => '0x3B', 'oct' => '073', 'char' => ';', 'detail' => ';'}, 
    {'dec' => '60', 'hex' => '0x3C', 'oct' => '074', 'char' => '<', 'detail' => '<'}, 
    {'dec' => '61', 'hex' => '0x3D', 'oct' => '075', 'char' => '=', 'detail' => '='}, 
    {'dec' => '62', 'hex' => '0x3E', 'oct' => '076', 'char' => '>', 'detail' => '>'}, 
    {'dec' => '63', 'hex' => '0x3F', 'oct' => '077', 'char' => '?', 'detail' => '?'}, 
    {'dec' => '64', 'hex' => '0x40', 'oct' => '100', 'char' => '@', 'detail' => '@'}, 
    {'dec' => '65', 'hex' => '0x41', 'oct' => '101', 'char' => 'A', 'detail' => 'A'}, 
    {'dec' => '66', 'hex' => '0x42', 'oct' => '102', 'char' => 'B', 'detail' => 'B'}, 
    {'dec' => '67', 'hex' => '0x43', 'oct' => '103', 'char' => 'C', 'detail' => 'C'}, 
    {'dec' => '68', 'hex' => '0x44', 'oct' => '104', 'char' => 'D', 'detail' => 'D'}, 
    {'dec' => '69', 'hex' => '0x45', 'oct' => '105', 'char' => 'E', 'detail' => 'E'}, 
    {'dec' => '70', 'hex' => '0x46', 'oct' => '106', 'char' => 'F', 'detail' => 'F'}, 
    {'dec' => '71', 'hex' => '0x47', 'oct' => '107', 'char' => 'G', 'detail' => 'G'}, 
    {'dec' => '72', 'hex' => '0x48', 'oct' => '110', 'char' => 'H', 'detail' => 'H'}, 
    {'dec' => '73', 'hex' => '0x49', 'oct' => '111', 'char' => 'I', 'detail' => 'I'}, 
    {'dec' => '74', 'hex' => '0x4A', 'oct' => '112', 'char' => 'J', 'detail' => 'J'}, 
    {'dec' => '75', 'hex' => '0x4B', 'oct' => '113', 'char' => 'K', 'detail' => 'K'}, 
    {'dec' => '76', 'hex' => '0x4C', 'oct' => '114', 'char' => 'L', 'detail' => 'L'}, 
    {'dec' => '77', 'hex' => '0x4D', 'oct' => '115', 'char' => 'M', 'detail' => 'M'}, 
    {'dec' => '78', 'hex' => '0x4E', 'oct' => '116', 'char' => 'N', 'detail' => 'N'}, 
    {'dec' => '79', 'hex' => '0x4F', 'oct' => '117', 'char' => 'O', 'detail' => 'O'}, 
    {'dec' => '80', 'hex' => '0x50', 'oct' => '120', 'char' => 'P', 'detail' => 'P'}, 
    {'dec' => '81', 'hex' => '0x51', 'oct' => '121', 'char' => 'Q', 'detail' => 'Q'}, 
    {'dec' => '82', 'hex' => '0x52', 'oct' => '122', 'char' => 'R', 'detail' => 'R'}, 
    {'dec' => '83', 'hex' => '0x53', 'oct' => '123', 'char' => 'S', 'detail' => 'S'}, 
    {'dec' => '84', 'hex' => '0x54', 'oct' => '124', 'char' => 'T', 'detail' => 'T'}, 
    {'dec' => '85', 'hex' => '0x55', 'oct' => '125', 'char' => 'U', 'detail' => 'U'}, 
    {'dec' => '86', 'hex' => '0x56', 'oct' => '126', 'char' => 'V', 'detail' => 'V'}, 
    {'dec' => '87', 'hex' => '0x57', 'oct' => '127', 'char' => 'W', 'detail' => 'W'}, 
    {'dec' => '88', 'hex' => '0x58', 'oct' => '130', 'char' => 'X', 'detail' => 'X'}, 
    {'dec' => '89', 'hex' => '0x59', 'oct' => '131', 'char' => 'Y', 'detail' => 'Y'}, 
    {'dec' => '90', 'hex' => '0x5A', 'oct' => '132', 'char' => 'Z', 'detail' => 'Z'}, 
    {'dec' => '91', 'hex' => '0x5B', 'oct' => '133', 'char' => '[', 'detail' => '['}, 
    {'dec' => '92', 'hex' => '0x5C', 'oct' => '134', 'char' => '\\', 'detail' => '\\'}, 
    {'dec' => '93', 'hex' => '0x5D', 'oct' => '135', 'char' => ']', 'detail' => ']'}, 
    {'dec' => '94', 'hex' => '0x5E', 'oct' => '136', 'char' => '^', 'detail' => '^'}, 
    {'dec' => '95', 'hex' => '0x5F', 'oct' => '137', 'char' => '_', 'detail' => '_'}, 
    {'dec' => '96', 'hex' => '0x60', 'oct' => '140', 'char' => '`', 'detail' => '`'}, 
    {'dec' => '97', 'hex' => '0x61', 'oct' => '141', 'char' => 'a', 'detail' => 'a'}, 
    {'dec' => '98', 'hex' => '0x62', 'oct' => '142', 'char' => 'b', 'detail' => 'b'}, 
    {'dec' => '99', 'hex' => '0x63', 'oct' => '143', 'char' => 'c', 'detail' => 'c'}, 
    {'dec' => '100', 'hex' => '0x64', 'oct' => '144', 'char' => 'd', 'detail' => 'd'}, 
    {'dec' => '101', 'hex' => '0x65', 'oct' => '145', 'char' => 'e', 'detail' => 'e'}, 
    {'dec' => '102', 'hex' => '0x66', 'oct' => '146', 'char' => 'f', 'detail' => 'f'}, 
    {'dec' => '103', 'hex' => '0x67', 'oct' => '147', 'char' => 'g', 'detail' => 'g'}, 
    {'dec' => '104', 'hex' => '0x68', 'oct' => '150', 'char' => 'h', 'detail' => 'h'}, 
    {'dec' => '105', 'hex' => '0x69', 'oct' => '151', 'char' => 'i', 'detail' => 'i'}, 
    {'dec' => '106', 'hex' => '0x6A', 'oct' => '152', 'char' => 'j', 'detail' => 'j'}, 
    {'dec' => '107', 'hex' => '0x6B', 'oct' => '153', 'char' => 'k', 'detail' => 'k'}, 
    {'dec' => '108', 'hex' => '0x6C', 'oct' => '154', 'char' => 'l', 'detail' => 'l'}, 
    {'dec' => '109', 'hex' => '0x6D', 'oct' => '155', 'char' => 'm', 'detail' => 'm'}, 
    {'dec' => '110', 'hex' => '0x6E', 'oct' => '156', 'char' => 'n', 'detail' => 'n'}, 
    {'dec' => '111', 'hex' => '0x6F', 'oct' => '157', 'char' => 'o', 'detail' => 'o'}, 
    {'dec' => '112', 'hex' => '0x70', 'oct' => '160', 'char' => 'p', 'detail' => 'p'}, 
    {'dec' => '113', 'hex' => '0x71', 'oct' => '161', 'char' => 'q', 'detail' => 'q'}, 
    {'dec' => '114', 'hex' => '0x72', 'oct' => '162', 'char' => 'r', 'detail' => 'r'}, 
    {'dec' => '115', 'hex' => '0x73', 'oct' => '163', 'char' => 's', 'detail' => 's'}, 
    {'dec' => '116', 'hex' => '0x74', 'oct' => '164', 'char' => 't', 'detail' => 't'}, 
    {'dec' => '117', 'hex' => '0x75', 'oct' => '165', 'char' => 'u', 'detail' => 'u'}, 
    {'dec' => '118', 'hex' => '0x76', 'oct' => '166', 'char' => 'v', 'detail' => 'v'}, 
    {'dec' => '119', 'hex' => '0x77', 'oct' => '167', 'char' => 'w', 'detail' => 'w'}, 
    {'dec' => '120', 'hex' => '0x78', 'oct' => '170', 'char' => 'x', 'detail' => 'x'}, 
    {'dec' => '121', 'hex' => '0x79', 'oct' => '171', 'char' => 'y', 'detail' => 'y'}, 
    {'dec' => '122', 'hex' => '0x7A', 'oct' => '172', 'char' => 'z', 'detail' => 'z'}, 
    {'dec' => '123', 'hex' => '0x7B', 'oct' => '173', 'char' => '{', 'detail' => '{'}, 
    {'dec' => '124', 'hex' => '0x7C', 'oct' => '174', 'char' => '|', 'detail' => '|'}, 
    {'dec' => '125', 'hex' => '0x7D', 'oct' => '175', 'char' => '}', 'detail' => '}'}, 
    {'dec' => '126', 'hex' => '0x7E', 'oct' => '176', 'char' => '~', 'detail' => '~'}, 
    {'dec' => '127', 'hex' => '0x7F', 'oct' => '177', 'char' => 'DEL', 'detail' => 'DEL'}
  );
  return @chars;
}

###############################################################################
#
#   Function:   shuffle
#   Purpose:    Randomize an array
#
#   Comments:   This routine was ripped from 'Perl Cookbook' pg 121-122
#               
###############################################################################
sub randomizeArray($)
{
  my($array) = shift;
  my($i) = scalar(@{$array});
  my($j) = 0;
  my($item) = '';
  foreach $item (@{$array})
  {
    --$i;
    $j = int rand ($i+1);
    next if $i == $j;
    @$array [$i,$j] = @$array[$j,$i];
  }#End foreach
  return @$array;
}



#declare an arrays for alpha and hex
my($answer) = 0;
my($count) = 0;
my($charSetString) = '';
my($score) = 0;
my($srcDataType) = '';
my($destDataType) = '';
my(@chars) = getChars();
my(@lowerAlpha) = (97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122);
my(@upperAlpha) = (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);
my(@numeric) = (48, 49, 50, 51, 52, 53, 54, 55, 56, 57);
my(@printableSpecial) = (32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 58, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 95, 96, 123, 124, 125, 126);
my(@nonPrintableSpecial) = (0, 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, 127);
my(@dataTypeArray) = ('dec', 'hex', 'oct', 'char');

print 'Choose (comma-delimited) character set(s) to use:' . "\n" . '1 = lower-case alphabetical' . "\n" . '2 = upper-case alphabetical' . "\n" . '3 = numeric' . "\n" . '4 = printable specials' . "\n" . '5 = non-printable specials:' . "\n";
$charSetString = <STDIN>;
chomp($charSetString);

print "\n\n" . '0 = decimal, 1 = hex, 2 = octal, 3 = character' . "\n";
print 'Choose which type of data you would like to have displayed, and which data' . "\n" . 'you would like to enter (eg. 1,2 to be shown hex and to enter decimal):' . "\n";
($srcDataType, $destDataType) = split(/,/, <STDIN>);
chomp($srcDataType);chomp($destDataType);

#If the user's an idiot, exit.
exit if((length($charSetString) == 0) || (length($destDataType) == 0) || ($destDataType eq $srcDataType) || (int($srcDataType) >= scalar(@dataTypeArray)) || (int($destDataType) >= scalar(@dataTypeArray)));

my(@chosenChars) = ();
push(@chosenChars, @lowerAlpha) if($charSetString =~ /1/);
push(@chosenChars, @upperAlpha) if($charSetString =~ /2/);
push(@chosenChars, @numeric) if($charSetString =~ /3/);
push(@chosenChars, @printableSpecial) if($charSetString =~ /4/);
push(@chosenChars, @nonPrintableSpecial) if($charSetString =~ /5/);
@chosenChars = randomizeArray(\@chosenChars);

#Go through all options and perform the testing.
for($count = 0; $count < scalar(@chosenChars); ++$count)
{
  #give the data to the user
  print $dataTypeArray[$srcDataType] . ': ' . $chars[$chosenChars[$count]]->{$dataTypeArray[$srcDataType]} . "\n";

  #get imput and compare it to the correct answer
  $answer = <STDIN>;
  chomp($answer); 
  if($chars[$chosenChars[$count]]->{$dataTypeArray[$destDataType]} =~ /$answer/i)
  {
    ++$score;
    print 'Correct.' . "\n\n";
  }#End if
  else
  {
    print 'NO HOSER!!!!' . "\n";
    print 'The answer is ' . $chars[$chosenChars[$count]]->{$dataTypeArray[$destDataType]} . "\n";
    print 'You said ' . $answer . "\n\n";
  }#End else 
}#End for


#print out their score, and make fun of the n3wbs
$score /= (scalar(@chosenChars) / 100);
print 'Your score is ' . $score . '%.' . "\n";

if($score eq 100)
{
  print "You are a l33t h4x0r\n";
}#End if
elsif($score >= 90)
{
  print "You are a h4x0r in training\n";
}
elsif($score >= 80)
{
  print "You are getting the hang of it\n";
}
else
{
  print "LOSER!!!!\n";
}#End else

print "\n" . 'Press [Enter] to exit.';
<STDIN>



