sub md4(@) {
    my @input = grep { defined && length > 0 } split /(.{64})/s, join '', @_;
    push @input, '' if !@input || length($input[$

    my @A = (0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476); 
    my @T = (0, 0x5A827999, 0x6ED9EBA1);
    my @L = qw(3 7 11 19 3 5 9 13 3 9 11 15);   
    my @O = (1, 4, 4,                           
             4, 1, 1,                           
             0, 0, 1);                          
    my @I = map {
                    my $z   = int $_/16;
                    my $x   = $_%4;
                    my $y   = int $_%16/4;
                    ($x,$y) = (R($x),R($y)) if $O[6+$z];
                    $O[$z] * $x + $O[3+$z] * $y
                } 0..47;

    my ($a,$b,$c,$d);
    my($l,$p) = (0,0);
    foreach (@input) {
        my $r = length($_);
        $l += $r;
        $r++, $_.="\x80" if $r<64 && !$p++;
        my @W = unpack 'V16', $_ . "\0"x7;
        push @W, (0)x16 if @W < 16;
        $W[14] = $l*8 if $r < 57;              
        ($a,$b,$c,$d) = @A;
        for (0..47) {
            my $z = int $_/16;
            $a = L($L[4*($_>>4) + $_%4],
                 M(&{(sub{$b&$c|~$b&$d},       
                      sub{$b&$c|$b&$d|$c&$d},  
                      sub{$b^$c^$d}            
                     )[$z]}
                   + $a + $W[$I[$_]] + $T[$z]));
            ($a,$b,$c,$d) = ($d,$a,$b,$c);
        }
        my @v = ($a, $b, $c, $d);
        $A[$_] = M($A[$_] + $v[$_]) for 0..3;
    }
    pack 'V4', @A;
}

sub L { 
    my ($n, $x) = @_;
    $x<<$n | 2**$n - 1 & $x>>(32-$n);
}

sub M { 
    no integer;
    my ($x) = @_;
    my $m = 1+0xffffffff;
    $x - $m * int $x/$m;
}

sub R { 
    my $n = pop;
    ($n&1)*2 + ($n&2)/2;
}

sub md4_hex(@) { 
  unpack 'H*', &md4;
}

print "Rosetta Code => " . md4_hex( "Rosetta Code" ) . "\n";