1#!/usr/bin/env perl 2 3## 4## Author......: See docs/credits.txt 5## License.....: MIT 6## 7 8use strict; 9use warnings; 10 11use Digest::MD5 qw (md5); 12use POSIX qw (ceil); 13 14sub module_constraints { [[-1, -1], [-1, -1], [0, 55], [1, 4], [-1, -1]] } 15 16sub pseudo_base64 17{ 18 my $itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 19 20 my $md5 = shift; 21 my $s64 = ""; 22 for my $i (0..3) { 23 my $v = unpack "V", substr ($md5, $i*4, 4); 24 for (1..4) { 25 $s64 .= substr ($itoa64, $v & 0x3f, 1); 26 $v >>= 6; 27 } 28 } 29 return $s64; 30} 31 32sub module_generate_hash 33{ 34 my $word = shift; 35 my $salt = shift; 36 37 my $word_salt = $word . $salt; 38 39 my $word_salt_len = length ($word_salt); 40 41 my $pad_len = ceil ($word_salt_len / 16) * 16; 42 43 my $digest = md5 ($word_salt . "\0" x ($pad_len - $word_salt_len)); 44 45 my $hash = sprintf ("%s:%s", pseudo_base64 ($digest), $salt); 46 47 return $hash; 48} 49 50sub module_verify_hash 51{ 52 my $line = shift; 53 54 my ($hash, $salt, $word) = split (':', $line); 55 56 return unless defined $hash; 57 return unless defined $salt; 58 return unless defined $word; 59 60 my $word_packed = pack_if_HEX_notation ($word); 61 62 my $new_hash = module_generate_hash ($word_packed, $salt); 63 64 return ($new_hash, $word); 65} 66 671; 68