MD4: Difference between revisions

243 bytes removed ,  4 months ago
m
(New post.)
m (→‎{{header|Wren}}: Minor tidy)
 
(8 intermediate revisions by 2 users not shown)
Line 590:
engine_update(string_to_byte_vector(text), 0, text.length());
 
const int32_t buffer_index = (static_cast<int32_t) >( count % BLOCK_LENGTH );
const int32_t padding_length = ( buffer_index < 56 ) ? 56 - buffer_index : 120 - buffer_index;
 
Line 597:
 
for ( int32_t i = 0; i < 8; ++i ) {
tail[padding_length + i] = static_cast<int8_t>(int8_t) unsigned_right_shift(count * 8, 8 * i));
}
 
Line 605:
for ( int32_t i = 0; i < 4; ++i ) {
for ( int32_t j = 0; j < 4; ++j ) {
result[i * 4 + j] = static_cast<int8_t>(int8_t) unsigned_right_shift(context[i], 8 * j));
}
}
Line 614:
 
private:
void engine_reset() {
count = 0;
context.assign(4, 0);
context[0] = 0x67452301;
context[1] = 0xefcdab89;
context[2] = 0x98badcfe;
context[3] = 0x10325476;
extra.assign(16, 0);
buffer.assign(BLOCK_LENGTH, 0);
}
 
void engine_update(const std::vector<int8_t>& message_bytes,
const int32_t& offset, const int32_t& message_length) {
Line 632 ⟶ 621:
}
 
int32_t buffer_index = (static_cast<int32_t) >( count % BLOCK_LENGTH );
count += message_length;
const int32_t partial_length = BLOCK_LENGTH - buffer_index;
Line 696 ⟶ 685:
context[2] += c;
context[3] += d;
}
 
void engine_reset() {
count = 0;
context.assign(4, 0);
context[0] = 0x67452301;
context[1] = 0xefcdab89;
context[2] = 0x98badcfe;
context[3] = 0x10325476;
extra.assign(16, 0);
buffer.assign(BLOCK_LENGTH, 0);
}
 
Line 703:
 
std::transform(text.begin(), text.end(), std::back_inserter(bytes),
[](char ch){ return (static_cast<int8_t) >(ch); });
 
return bytes;
Line 709:
 
int32_t unsigned_right_shift(const int32_t& base, const int32_t& shift) {
if ( baseshift ==< 0 || shift >= 32 || base == 0 ) {
return 0;
}
return ( base > 0 ) ? base >> shift : static_cast<uint32_t>( base + 4'294'967'296 ) >> shift;
}
 
Line 1,982:
(formerly Perl 6)
<syntaxhighlight lang="raku" line>sub md4($str) {
my @buf8 $buf .= new: $str.ordsencode;
my $buflenbuf-length = @$buf.elems;
$buf.push: 0x80;
$buf.push: 0 until ($buf - (448 div 8)) %% (512 div 8);
# raku serializes in little endian by default
$buf.write-uint64: $buf.elems, $buf-length*8;
 
my \mask(&f, =&g, (1&h, +< 32&r) -= 1;
my &f = -> $x, $y, $z { ($^x +& $^y) +| (+^$x +^ mask) +& $^z },
my &g = -> $x, $y, $z { ($^x +& $^y) +| ($x +& $^z) +| ($y +& $z) },
my &h = -> $x, $y, $z { $^x +^ $^y +^ $^z },
# for some reason we have to type v here
my &r = -> $v, $s { (($v +< $s) +& mask) +| (($v +& mask) +> (32 - $s)) }
-> uint32 $v, $s { $v +< $s +| $v +> (32 - $s) }
 
my uint32 ($a, $b, $c, $d) = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;
sub pack-le (@a) {
gather for @a -> $a,$b,$c,$d { take $d +< 24 + $c +< 16 + $b +< 8 + $a }
}
loop (my $pos = 0; $pos < $buf.elems; $pos+=64) {
my ($a, $b, $c, $d) = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;
my ($aa, $bb, $cc, $dd) = $a, $b, $c, $d;
for 0, 4, 8, 12 -> $i {
my $term = False;
$a = r($a + f($b, $c, $d) + $buf.read-uint32($pos+($i+0)*4), 3);
my $last = False;
$d = r($d + f($a, $b, $c) + $buf.read-uint32($pos+($i+1)*4), 7);
my $off = 0;
$c = r($c + f($d, $a, $b) + $buf.read-uint32($pos+($i+2)*4), 11);
repeat until $last {
my @block $b = @buf[r($off..$offb +63]:v; f($offc, $d, $a) += 64$buf.read-uint32($pos+($i+3)*4), 19);
}
myfor @x;0, 1, 2, 3 -> $i {
$a = r($a + g($b, $c, $d) + $buf.read-uint32($pos+($i+0 )*4) + 0x5a827999, 3);
given +@block {
$d = r($d + g($a, $b, $c) + $buf.read-uint32($pos+($i+4 )*4) + 0x5a827999, 5);
when 64 {
$c = r($c + g($d, $a, $b) + $buf.read-uint32($pos+($i+8 )*4) + 0x5a827999, 9);
@x = pack-le @block;
$b = r($b + g($c, $d, $a) + $buf.read-uint32($pos+($i+12)*4) + 0x5a827999, 13);
}
when 56..63 { }
$termfor =0, 2, 1, 3 -> $i True;{
$a = r($a + h($b, $c, $d) + $buf.read-uint32($pos+($i+0 )*4) + 0x6ed9eba1, 3);
@block.push(0x80);
$d = r($d + h($a, $b, $c) + $buf.read-uint32($pos+($i+4 )*4) + 0x6ed9eba1, 9);
@block.push(slip 0 xx 63 - $_);
$c = r($c + h($d, $a, $b) + $buf.read-uint32($pos+($i+8 )*4) + 0x6ed9eba1, 11);
@x = pack-le @block;
$b = r($b + h($c, $d, $a) + $buf.read-uint32($pos+($i+12)*4) + 0x6ed9eba1, 15);
}
when 0..55 { }
@block.push($terma,$b,$c,$d) ??Z[+=] 0 !! 0x80($aa,$bb,$cc,$dd);
@block.push(slip 0 xx 55 - $_);
@x = pack-le @block;
my $bit_len = $buflen +< 3;
@x.push: $bit_len +& mask, $bit_len +> 32;
$last = True;
}
default {
die "oops";
}
}
my ($aa, $bb, $cc, $dd) = $a, $b, $c, $d;
for 0, 4, 8, 12 -> \i {
$a = r($a + f($b, $c, $d) + @x[ i+0 ], 3);
$d = r($d + f($a, $b, $c) + @x[ i+1 ], 7);
$c = r($c + f($d, $a, $b) + @x[ i+2 ], 11);
$b = r($b + f($c, $d, $a) + @x[ i+3 ], 19);
}
for 0, 1, 2, 3 -> \i {
$a = r($a + g($b, $c, $d) + @x[ i+0 ] + 0x5a827999, 3);
$d = r($d + g($a, $b, $c) + @x[ i+4 ] + 0x5a827999, 5);
$c = r($c + g($d, $a, $b) + @x[ i+8 ] + 0x5a827999, 9);
$b = r($b + g($c, $d, $a) + @x[ i+12] + 0x5a827999, 13);
}
for 0, 2, 1, 3 -> \i {
$a = r($a + h($b, $c, $d) + @x[ i+0 ] + 0x6ed9eba1, 3);
$d = r($d + h($a, $b, $c) + @x[ i+8 ] + 0x6ed9eba1, 9);
$c = r($c + h($d, $a, $b) + @x[ i+4 ] + 0x6ed9eba1, 11);
$b = r($b + h($c, $d, $a) + @x[ i+12] + 0x6ed9eba1, 15);
}
$a = ($a + $aa) +& mask;
$b = ($b + $bb) +& mask;
$c = ($c + $cc) +& mask;
$d = ($d + $dd) +& mask;
}
reduce { $^buf.write-uint32: $buf.elems, $^x; $buf }, buf8.new, $a, $b, $c, $d;
sub b2l($n is copy) {
my $x = 0;
for ^4 {
$x +<= 8;
$x += $n +& 0xff;
$n +>= 8;
}
$x;
}
 
b2l($a) +< 96 +
b2l($b) +< 64 +
b2l($c) +< 32 +
b2l($d);
}
CHECK {
sub MAIN {
use Test;
my $str = 'Rosetta Code';
plan 1;
say md4($str).base(16).lc;
is md4('Rosetta Code').list.fmt('%02X'), 'A5 2B CF C6 A0 D0 D3 00 CD C5 DD BF BE FE 47 8B';
}</syntaxhighlight>
{{out}}
<pre>1..1
<pre>a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>
ok 1 -
</pre>
 
=={{header|Ruby}}==
Line 2,411 ⟶ 2,369:
{{trans|D}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="ecmascriptwren">import "./fmt" for Fmt
 
var toBytes = Fn.new { |val|
9,482

edits