From 7148aa6706b8657799f2a688427b46d613530297 Mon Sep 17 00:00:00 2001 From: mhasbini Date: Thu, 14 Feb 2019 01:22:16 +0200 Subject: [PATCH] Add unit tests for several modes: 4900, 5300, 5400, 5700, 5800, 6000, 6100, 6400 & 6500 --- tools/test_modules/m04900.pm | 44 ++++++++++++ tools/test_modules/m05300.pm | 90 ++++++++++++++++++++++++ tools/test_modules/m05400.pm | 90 ++++++++++++++++++++++++ tools/test_modules/m05700.pm | 62 +++++++++++++++++ tools/test_modules/m05800.pm | 64 +++++++++++++++++ tools/test_modules/m06000.pm | 42 ++++++++++++ tools/test_modules/m06100.pm | 42 ++++++++++++ tools/test_modules/m06400.pm | 117 +++++++++++++++++++++++++++++++ tools/test_modules/m06500.pm | 129 +++++++++++++++++++++++++++++++++++ 9 files changed, 680 insertions(+) create mode 100644 tools/test_modules/m04900.pm create mode 100644 tools/test_modules/m05300.pm create mode 100644 tools/test_modules/m05400.pm create mode 100644 tools/test_modules/m05700.pm create mode 100644 tools/test_modules/m05800.pm create mode 100644 tools/test_modules/m06000.pm create mode 100644 tools/test_modules/m06100.pm create mode 100644 tools/test_modules/m06400.pm create mode 100644 tools/test_modules/m06500.pm diff --git a/tools/test_modules/m04900.pm b/tools/test_modules/m04900.pm new file mode 100644 index 000000000..28c5ac419 --- /dev/null +++ b/tools/test_modules/m04900.pm @@ -0,0 +1,44 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA qw (sha1_hex); + +sub module_constraints { [[0, 255], [0, 127], [0, 27], [0, 27], [0, 27]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $digest = sha1_hex ($salt . $word . $salt); + + my $hash = sprintf ("%s:%s", $digest, $salt); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $salt, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $salt; + return unless defined $word; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m05300.pm b/tools/test_modules/m05300.pm new file mode 100644 index 000000000..36fdc5d26 --- /dev/null +++ b/tools/test_modules/m05300.pm @@ -0,0 +1,90 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::MD5 qw (md5); +use Digest::HMAC qw (hmac hmac_hex); + +sub module_constraints { [[0, 255], [-1, -1], [0, 55], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift || get_random_ike_salt (); + + my @salt_arr = split (":", $salt); + + my $msg = pack ("H*", $salt_arr[0] . $salt_arr[1] . $salt_arr[2] . $salt_arr[3] . $salt_arr[4] . $salt_arr[5]); + my $nr = pack ("H*", $salt_arr[6] . $salt_arr[7]); + + my $digest = hmac ($nr , $word, \&md5, 64); + $digest = hmac_hex ($msg, $digest, \&md5, 64); + + my $hash = sprintf ("%s:%s", $salt, $digest); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my @data = split (':', $line); + + return unless scalar @data == 10; + + my $hash = $data[0]; + my $salt = join ('', @data[1 .. 8]); + my $word = $data[9]; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +sub get_random_ike_salt +{ + my $nr_buf = ""; + + for (my $i = 0; $i < 40; $i++) + { + $nr_buf .= get_random_chr (0, 0xff); + } + + my $msg_buf = ""; + + for (my $i = 0; $i < 440; $i++) + { + $msg_buf .= get_random_chr (0, 0xff); + } + + my $nr_buf_hex = unpack ("H*", $nr_buf); + my $msg_buf_hex = unpack ("H*", $msg_buf); + + my $salt_buf = sprintf ("%s:%s:%s:%s:%s:%s:%s:%s", substr ($msg_buf_hex, 0, 256), substr ($msg_buf_hex, 256, 256), substr ($msg_buf_hex, 512, 16), substr ($msg_buf_hex, 528, 16), substr ($msg_buf_hex, 544, 320), substr ($msg_buf_hex, 864, 16), substr ($nr_buf_hex, 0, 40), substr ($nr_buf_hex, 40, 40)); + + return $salt_buf; +} + +sub get_random_chr +{ + return chr get_random_num (@_); +} + +sub get_random_num +{ + my $min = shift; + my $max = shift; + + return int ((rand ($max - $min)) + $min); +} + +1; diff --git a/tools/test_modules/m05400.pm b/tools/test_modules/m05400.pm new file mode 100644 index 000000000..7aed67f5f --- /dev/null +++ b/tools/test_modules/m05400.pm @@ -0,0 +1,90 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Digest::SHA qw (sha1); +use Digest::HMAC qw (hmac hmac_hex); + +sub module_constraints { [[0, 255], [-1, -1], [0, 55], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift || get_random_ike_salt (); + + my @salt_arr = split (":", $salt); + + my $msg = pack ("H*", $salt_arr[0] . $salt_arr[1] . $salt_arr[2] . $salt_arr[3] . $salt_arr[4] . $salt_arr[5]); + my $nr = pack ("H*", $salt_arr[6] . $salt_arr[7]); + + my $digest = hmac ($nr , $word, \&sha1, 64); + $digest = hmac_hex ($msg, $digest, \&sha1, 64); + + my $hash = sprintf ("%s:%s", $salt, $digest); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my @data = split (':', $line); + + return unless scalar @data == 10; + + my $hash = $data[0]; + my $salt = join ('', @data[1 .. 8]); + my $word = $data[9]; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +sub get_random_ike_salt +{ + my $nr_buf = ""; + + for (my $i = 0; $i < 40; $i++) + { + $nr_buf .= get_random_chr (0, 0xff); + } + + my $msg_buf = ""; + + for (my $i = 0; $i < 440; $i++) + { + $msg_buf .= get_random_chr (0, 0xff); + } + + my $nr_buf_hex = unpack ("H*", $nr_buf); + my $msg_buf_hex = unpack ("H*", $msg_buf); + + my $salt_buf = sprintf ("%s:%s:%s:%s:%s:%s:%s:%s", substr ($msg_buf_hex, 0, 256), substr ($msg_buf_hex, 256, 256), substr ($msg_buf_hex, 512, 16), substr ($msg_buf_hex, 528, 16), substr ($msg_buf_hex, 544, 320), substr ($msg_buf_hex, 864, 16), substr ($nr_buf_hex, 0, 40), substr ($nr_buf_hex, 40, 40)); + + return $salt_buf; +} + +sub get_random_chr +{ + return chr get_random_num (@_); +} + +sub get_random_num +{ + my $min = shift; + my $max = shift; + + return int ((rand ($max - $min)) + $min); +} + +1; diff --git a/tools/test_modules/m05700.pm b/tools/test_modules/m05700.pm new file mode 100644 index 000000000..98ecf24d1 --- /dev/null +++ b/tools/test_modules/m05700.pm @@ -0,0 +1,62 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; + +use Digest::SHA qw (sha256); +use MIME::Base64 qw (encode_base64); + +sub module_constraints { [[0, 255], [-1, -1], [0, 55], [-1, -1], [-1, -1]] } + +my $CISCO_BASE64_MAPPING = +{ + 'A', '.', 'B', '/', 'C', '0', 'D', '1', 'E', '2', 'F', '3', 'G', '4', 'H', + '5', 'I', '6', 'J', '7', 'K', '8', 'L', '9', 'M', 'A', 'N', 'B', 'O', 'C', + 'P', 'D', 'Q', 'E', 'R', 'F', 'S', 'G', 'T', 'H', 'U', 'I', 'V', 'J', 'W', + 'K', 'X', 'L', 'Y', 'M', 'Z', 'N', 'a', 'O', 'b', 'P', 'c', 'Q', 'd', 'R', + 'e', 'S', 'f', 'T', 'g', 'U', 'h', 'V', 'i', 'W', 'j', 'X', 'k', 'Y', 'l', + 'Z', 'm', 'a', 'n', 'b', 'o', 'c', 'p', 'd', 'q', 'e', 'r', 'f', 's', 'g', + 't', 'h', 'u', 'i', 'v', 'j', 'w', 'k', 'x', 'l', 'y', 'm', 'z', 'n', '0', + 'o', '1', 'p', '2', 'q', '3', 'r', '4', 's', '5', 't', '6', 'u', '7', 'v', + '8', 'w', '9', 'x', '+', 'y', '/', 'z' +}; + +sub module_generate_hash +{ + my $word = shift; + + my $digest = sha256 ($word); + + my $base64_buf = encode_base64 ($digest, ""); + + my $hash = ""; + + for (my $i = 0; $i < 43; $i++) + { + $hash .= $CISCO_BASE64_MAPPING->{substr ($base64_buf, $i, 1)}; + } + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $word; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m05800.pm b/tools/test_modules/m05800.pm new file mode 100644 index 000000000..6784714b4 --- /dev/null +++ b/tools/test_modules/m05800.pm @@ -0,0 +1,64 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; + +use Digest::SHA qw (sha1); + +sub module_constraints { [[0, 231], [1, 16], [0, 31], [1, 16], [0, 31]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + + my $digest = androidpin_hash ($word, $salt); + + my $hash = sprintf ("%s:%s", $digest, $salt); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $salt, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $salt; + return unless defined $word; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt); + + return ($new_hash, $word); +} + +sub androidpin_hash +{ + my $word = shift; + my $salt = shift; + + my $w = sprintf ("%d%s%s", 0, $word, $salt); + + my $digest = sha1 ($w); + + for (my $i = 1; $i < 1024; $i++) + { + $w = $digest . sprintf ("%d%s%s", $i, $word, $salt); + + $digest = sha1 ($w); + } + + my ($A, $B, $C, $D, $E) = unpack ("N5", $digest); + + return sprintf ("%08x%08x%08x%08x%08x", $A, $B, $C, $D, $E); +} + +1; diff --git a/tools/test_modules/m06000.pm b/tools/test_modules/m06000.pm new file mode 100644 index 000000000..ab3a59d3c --- /dev/null +++ b/tools/test_modules/m06000.pm @@ -0,0 +1,42 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Crypt::Digest::RIPEMD160 qw (ripemd160_hex); + +sub module_constraints { [[0, 255], [-1, -1], [0, 55], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + + my $digest = ripemd160_hex ($word); + + my $hash = sprintf ("%s", $digest); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $word; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m06100.pm b/tools/test_modules/m06100.pm new file mode 100644 index 000000000..36780f55c --- /dev/null +++ b/tools/test_modules/m06100.pm @@ -0,0 +1,42 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Crypt::Digest::Whirlpool qw (whirlpool_hex); + +sub module_constraints { [[0, 255], [-1, -1], [0, 55], [-1, -1], [-1, -1]] } + +sub module_generate_hash +{ + my $word = shift; + + my $digest = whirlpool_hex ($word); + + my $hash = sprintf ("%s", $digest); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $word; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed); + + return ($new_hash, $word); +} + +1; diff --git a/tools/test_modules/m06400.pm b/tools/test_modules/m06400.pm new file mode 100644 index 000000000..8aaca3dec --- /dev/null +++ b/tools/test_modules/m06400.pm @@ -0,0 +1,117 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Crypt::PBKDF2; + +sub module_constraints { [[0, 255], [16, 16], [0, 55], [16, 16], [0, 55]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + my $iter = shift; + + my $iterations = 64; + + if (length ($iter)) + { + $iterations = 1 << int ($iter); + } + + my $digest = aix_ssha256_pbkdf2 ($word, $salt, $iterations); + + return sprintf ("{ssha256}%02i\$%s\$%s", log ($iterations) / log (2), $salt, $digest); +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $word; + + my $signature = substr ($hash, 0, 9); + + return unless ($signature eq "{ssha256}"); + + $hash = substr ($hash, 9); + + my @data = split ('\$', $hash); + + return unless scalar @data == 3; + + my $iter = shift (@data); + my $salt = shift @data; + my $digest = shift @data; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt, $iter); + + return ($new_hash, $word); +} + +sub aix_ssha256_pbkdf2 +{ + my $word_buf = shift; + my $salt_buf = shift; + my $iterations = shift; + + my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 256); + + my $pbkdf2 = Crypt::PBKDF2->new ( + hasher => $hasher, + iterations => $iterations, + output_len => 32 + ); + + my $hash_buf = $pbkdf2->PBKDF2 ($salt_buf, $word_buf); + + my $tmp_hash = ""; + + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 0, 1))) << 16) | (int (ord (substr ($hash_buf, 1, 1))) << 8) | (int (ord (substr ($hash_buf, 2, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 3, 1))) << 16) | (int (ord (substr ($hash_buf, 4, 1))) << 8) | (int (ord (substr ($hash_buf, 5, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 6, 1))) << 16) | (int (ord (substr ($hash_buf, 7, 1))) << 8) | (int (ord (substr ($hash_buf, 8, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 9, 1))) << 16) | (int (ord (substr ($hash_buf, 10, 1))) << 8) | (int (ord (substr ($hash_buf, 11, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 12, 1))) << 16) | (int (ord (substr ($hash_buf, 13, 1))) << 8) | (int (ord (substr ($hash_buf, 14, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 15, 1))) << 16) | (int (ord (substr ($hash_buf, 16, 1))) << 8) | (int (ord (substr ($hash_buf, 17, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 18, 1))) << 16) | (int (ord (substr ($hash_buf, 19, 1))) << 8) | (int (ord (substr ($hash_buf, 20, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 21, 1))) << 16) | (int (ord (substr ($hash_buf, 22, 1))) << 8) | (int (ord (substr ($hash_buf, 23, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 24, 1))) << 16) | (int (ord (substr ($hash_buf, 25, 1))) << 8) | (int (ord (substr ($hash_buf, 26, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 27, 1))) << 16) | (int (ord (substr ($hash_buf, 28, 1))) << 8) | (int (ord (substr ($hash_buf, 29, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 30, 1))) << 16) | (int (ord (substr ($hash_buf, 31, 1))) << 8) , 3); + + return $tmp_hash; +} + +sub to64 +{ + my $v = shift; + my $n = shift; + + my $itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + my $ret = ""; + + while (($n - 1) >= 0) + { + $n = $n - 1; + + $ret .= substr ($itoa64, $v & 0x3f, 1); + + $v = $v >> 6; + } + + return $ret +} + +1; diff --git a/tools/test_modules/m06500.pm b/tools/test_modules/m06500.pm new file mode 100644 index 000000000..7241fe5a2 --- /dev/null +++ b/tools/test_modules/m06500.pm @@ -0,0 +1,129 @@ +#!/usr/bin/env perl + +## +## Author......: See docs/credits.txt +## License.....: MIT +## + +use strict; +use warnings; + +use Crypt::PBKDF2; + +sub module_constraints { [[0, 255], [16, 16], [0, 55], [16, 16], [0, 55]] } + +sub module_generate_hash +{ + my $word = shift; + my $salt = shift; + my $iter = shift; + + my $iterations = 64; + + if (length ($iter)) + { + $iterations = 1 << int ($iter); + } + + my $digest = aix_ssha512_pbkdf2 ($word, $salt, $iterations); + + my $hash = sprintf ("{ssha512}%02i\$%s\$%s", log ($iterations) / log (2), $salt, $digest); + + return $hash; +} + +sub module_verify_hash +{ + my $line = shift; + + my ($hash, $word) = split (':', $line); + + return unless defined $hash; + return unless defined $word; + + my $signature = substr ($hash, 0, 9); + + return unless ($signature eq "{ssha512}"); + + $hash = substr ($hash, 9); + + my @data = split ('\$', $hash); + + return unless scalar @data == 3; + + my $iter = shift (@data); + my $salt = shift @data; + my $digest = shift @data; + + my $word_packed = pack_if_HEX_notation ($word); + + my $new_hash = module_generate_hash ($word_packed, $salt, $iter); + + return ($new_hash, $word); +} + +sub aix_ssha512_pbkdf2 +{ + my $word_buf = shift; + my $salt_buf = shift; + my $iterations = shift; + + my $hasher = Crypt::PBKDF2->hasher_from_algorithm ('HMACSHA2', 512); + + my $pbkdf2 = Crypt::PBKDF2->new ( + hasher => $hasher, + iterations => $iterations, + ); + + my $hash_buf = $pbkdf2->PBKDF2 ($salt_buf, $word_buf); + + my $tmp_hash = ""; + + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 0, 1))) << 16) | (int (ord (substr ($hash_buf, 1, 1))) << 8) | (int (ord (substr ($hash_buf, 2, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 3, 1))) << 16) | (int (ord (substr ($hash_buf, 4, 1))) << 8) | (int (ord (substr ($hash_buf, 5, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 6, 1))) << 16) | (int (ord (substr ($hash_buf, 7, 1))) << 8) | (int (ord (substr ($hash_buf, 8, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 9, 1))) << 16) | (int (ord (substr ($hash_buf, 10, 1))) << 8) | (int (ord (substr ($hash_buf, 11, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 12, 1))) << 16) | (int (ord (substr ($hash_buf, 13, 1))) << 8) | (int (ord (substr ($hash_buf, 14, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 15, 1))) << 16) | (int (ord (substr ($hash_buf, 16, 1))) << 8) | (int (ord (substr ($hash_buf, 17, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 18, 1))) << 16) | (int (ord (substr ($hash_buf, 19, 1))) << 8) | (int (ord (substr ($hash_buf, 20, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 21, 1))) << 16) | (int (ord (substr ($hash_buf, 22, 1))) << 8) | (int (ord (substr ($hash_buf, 23, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 24, 1))) << 16) | (int (ord (substr ($hash_buf, 25, 1))) << 8) | (int (ord (substr ($hash_buf, 26, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 27, 1))) << 16) | (int (ord (substr ($hash_buf, 28, 1))) << 8) | (int (ord (substr ($hash_buf, 29, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 30, 1))) << 16) | (int (ord (substr ($hash_buf, 31, 1))) << 8) | (int (ord (substr ($hash_buf, 32, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 33, 1))) << 16) | (int (ord (substr ($hash_buf, 34, 1))) << 8) | (int (ord (substr ($hash_buf, 35, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 36, 1))) << 16) | (int (ord (substr ($hash_buf, 37, 1))) << 8) | (int (ord (substr ($hash_buf, 38, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 39, 1))) << 16) | (int (ord (substr ($hash_buf, 40, 1))) << 8) | (int (ord (substr ($hash_buf, 41, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 42, 1))) << 16) | (int (ord (substr ($hash_buf, 43, 1))) << 8) | (int (ord (substr ($hash_buf, 44, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 45, 1))) << 16) | (int (ord (substr ($hash_buf, 46, 1))) << 8) | (int (ord (substr ($hash_buf, 47, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 48, 1))) << 16) | (int (ord (substr ($hash_buf, 49, 1))) << 8) | (int (ord (substr ($hash_buf, 50, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 51, 1))) << 16) | (int (ord (substr ($hash_buf, 52, 1))) << 8) | (int (ord (substr ($hash_buf, 53, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 54, 1))) << 16) | (int (ord (substr ($hash_buf, 55, 1))) << 8) | (int (ord (substr ($hash_buf, 56, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 57, 1))) << 16) | (int (ord (substr ($hash_buf, 58, 1))) << 8) | (int (ord (substr ($hash_buf, 59, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 60, 1))) << 16) | (int (ord (substr ($hash_buf, 61, 1))) << 8) | (int (ord (substr ($hash_buf, 62, 1)))), 4); + $tmp_hash .= to64 ((int (ord (substr ($hash_buf, 63, 1))) << 16) , 2); + + return $tmp_hash; +} + +sub to64 +{ + my $v = shift; + my $n = shift; + + my $itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + + my $ret = ""; + + while (($n - 1) >= 0) + { + $n = $n - 1; + + $ret .= substr ($itoa64, $v & 0x3f, 1); + + $v = $v >> 6; + } + + return $ret +} + +1;