2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,3 +1,4 @@
|
|||
NB. convert/misc/md5
|
||||
NB. RSA Data Security, Inc. MD5 Message-Digest Algorithm
|
||||
NB. version: 1.0.2
|
||||
NB.
|
||||
|
|
@ -6,18 +7,32 @@ NB. J implementation -- (C) 2003 Oleg Kobchenko;
|
|||
NB.
|
||||
NB. 09/04/2003 Oleg Kobchenko
|
||||
NB. 03/31/2007 Oleg Kobchenko j601, JAL
|
||||
NB. 12/17/2015 G.Pruss 64-bit
|
||||
NB. ~60+ times slower than using the jqt library
|
||||
|
||||
require 'convert'
|
||||
coclass 'pcrypt'
|
||||
|
||||
NB. lt= (*. -.)~ gt= *. -. ge= +. -. xor= ~:
|
||||
'`lt gt ge xor'=: (20 b.)`(18 b.)`(27 b.)`(22 b.)
|
||||
'`and or rot sh'=: (17 b.)`(23 b.)`(32 b.)`(33 b.)
|
||||
'`and or sh'=: (17 b.)`(23 b.)`(33 b.)
|
||||
|
||||
3 : 0 ''
|
||||
if. IF64 do.
|
||||
rot=: (16bffffffff and sh or ] sh~ 32 -~ [) NB. (y << x) | (y >>> (32 - x))
|
||||
add=: ((16bffffffff&and)@+)"0
|
||||
else.
|
||||
rot=: (32 b.)
|
||||
add=: (+&(_16&sh) (16&sh@(+ _16&sh) or and&65535@]) +&(and&65535))"0
|
||||
end.
|
||||
EMPTY
|
||||
)
|
||||
|
||||
hexlist=: tolower@:,@:hfd@:,@:(|."1)@(256 256 256 256&#:)
|
||||
|
||||
cmn=: 4 : 0
|
||||
'x s t'=. x [ 'q a b'=. y
|
||||
b add s rot (a add q) add (x add t)
|
||||
'x s t'=. x [ 'q a b'=. y
|
||||
b add s rot (a add q) add (x add t)
|
||||
)
|
||||
|
||||
ff=: cmn (((1&{ and 2&{) or 1&{ lt 3&{) , 2&{.)
|
||||
|
|
@ -27,55 +42,57 @@ ii=: cmn (( 2&{ xor 1&{ ge 3&{ ) , 2&{.)
|
|||
op=: ff`gg`hh`ii
|
||||
|
||||
I=: ".;._2(0 : 0)
|
||||
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
1 6 11 0 5 10 15 4 9 14 3 8 13 2 7 12
|
||||
5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
|
||||
0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9
|
||||
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
1 6 11 0 5 10 15 4 9 14 3 8 13 2 7 12
|
||||
5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2
|
||||
0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9
|
||||
)
|
||||
S=: 4 4$7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21
|
||||
|
||||
T=: |:".;._2(0 : 0)
|
||||
_680876936 _165796510 _378558 _198630844
|
||||
_389564586 _1069501632 _2022574463 1126891415
|
||||
606105819 643717713 1839030562 _1416354905
|
||||
_1044525330 _373897302 _35309556 _57434055
|
||||
_176418897 _701558691 _1530992060 1700485571
|
||||
1200080426 38016083 1272893353 _1894986606
|
||||
_1473231341 _660478335 _155497632 _1051523
|
||||
_45705983 _405537848 _1094730640 _2054922799
|
||||
1770035416 568446438 681279174 1873313359
|
||||
_1958414417 _1019803690 _358537222 _30611744
|
||||
_42063 _187363961 _722521979 _1560198380
|
||||
_1990404162 1163531501 76029189 1309151649
|
||||
1804603682 _1444681467 _640364487 _145523070
|
||||
_40341101 _51403784 _421815835 _1120210379
|
||||
_1502002290 1735328473 530742520 718787259
|
||||
1236535329 _1926607734 _995338651 _343485551
|
||||
_680876936 _165796510 _378558 _198630844
|
||||
_389564586 _1069501632 _2022574463 1126891415
|
||||
606105819 643717713 1839030562 _1416354905
|
||||
_1044525330 _373897302 _35309556 _57434055
|
||||
_176418897 _701558691 _1530992060 1700485571
|
||||
1200080426 38016083 1272893353 _1894986606
|
||||
_1473231341 _660478335 _155497632 _1051523
|
||||
_45705983 _405537848 _1094730640 _2054922799
|
||||
1770035416 568446438 681279174 1873313359
|
||||
_1958414417 _1019803690 _358537222 _30611744
|
||||
_42063 _187363961 _722521979 _1560198380
|
||||
_1990404162 1163531501 76029189 1309151649
|
||||
1804603682 _1444681467 _640364487 _145523070
|
||||
_40341101 _51403784 _421815835 _1120210379
|
||||
_1502002290 1735328473 530742520 718787259
|
||||
1236535329 _1926607734 _995338651 _343485551
|
||||
)
|
||||
|
||||
norm=: 3 : 0
|
||||
n=. 16 * 1 + _6 sh 8 + #y
|
||||
b=. n#0 [ y=. a.i.y
|
||||
for_i. i. #y do.
|
||||
b=. ((j { b) or (8*4|i) sh i{y) (j=. _2 sh i) } b
|
||||
end.
|
||||
b=. ((j { b) or (8*4|i) sh 128) (j=._2 sh i=.#y) } b
|
||||
_16]\ (8 * #y) (n-2) } b
|
||||
n=. 16 * 1 + _6 sh 8 + #y
|
||||
b=. n#0 [ y=. a.i.y
|
||||
for_i. i. #y do.
|
||||
b=. ((j { b) or (8*4|i) sh i{y) (j=. _2 sh i) } b
|
||||
end.
|
||||
b=. ((j { b) or (8*4|i) sh 128) (j=._2 sh i=.#y) } b
|
||||
_16]\ (8 * #y) (n-2) } b
|
||||
)
|
||||
|
||||
NB.*md5 v MD5 Message-Digest Algorithm
|
||||
NB. diagest=. md5 message
|
||||
md5=: 3 : 0
|
||||
X=. norm y
|
||||
q=. r=. 1732584193 _271733879 _1732584194 271733878
|
||||
for_x. X do.
|
||||
for_j. i.4 do.
|
||||
l=. ((j{I){x) ,. (16$j{S) ,. j{T
|
||||
for_i. i.16 do.
|
||||
r=. _1|.((i{l) (op@.j) r),}.r
|
||||
end.
|
||||
X=. norm y
|
||||
q=. r=. 1732584193 _271733879 _1732584194 271733878
|
||||
for_x. X do.
|
||||
for_j. i.4 do.
|
||||
l=. ((j{I){x) ,. (16$j{S) ,. j{T
|
||||
for_i. i.16 do.
|
||||
r=. _1|.((i{l) (op@.j) r),}.r
|
||||
end.
|
||||
q=. r=. r add q
|
||||
end.
|
||||
hexlist r
|
||||
q=. r=. r add q
|
||||
end.
|
||||
hexlist r
|
||||
)
|
||||
|
||||
md5_z_=: md5_pcrypt_
|
||||
|
|
|
|||
|
|
@ -1,25 +1,22 @@
|
|||
use Test;
|
||||
sub infix:<⊞>(uint32 $a, uint32 $b --> uint32) { ($a + $b) +& 0xffffffff }
|
||||
sub infix:«<<<»(uint32 $a, UInt $n --> uint32) { ($a +< $n) +& 0xffffffff +| ($a +> (32-$n)) }
|
||||
|
||||
sub prefix:<¬>(\x) { (+^ x) % 2**32 }
|
||||
sub infix:<⊞>(\x, \y) { (x + y) % 2**32 }
|
||||
sub infix:«<<<»(\x, \n) { (x +< n) % 2**32 +| (x +> (32-n)) }
|
||||
constant FGHI = { ($^a +& $^b) +| (+^$a +& $^c) },
|
||||
{ ($^a +& $^c) +| ($^b +& +^$c) },
|
||||
{ $^a +^ $^b +^ $^c },
|
||||
{ $^b +^ ($^a +| +^$^c) };
|
||||
|
||||
constant FGHI = -> \X, \Y, \Z { (X +& Y) +| (¬X +& Z) },
|
||||
-> \X, \Y, \Z { (X +& Z) +| (Y +& ¬Z) },
|
||||
-> \X, \Y, \Z { X +^ Y +^ Z },
|
||||
-> \X, \Y, \Z { Y +^ (X +| ¬Z) };
|
||||
|
||||
constant S = flat (7, 12, 17, 22) xx 4,
|
||||
(5, 9, 14, 20) xx 4,
|
||||
(4, 11, 16, 23) xx 4,
|
||||
(6, 10, 15, 21) xx 4;
|
||||
constant _S = flat (7, 12, 17, 22) xx 4,
|
||||
(5, 9, 14, 20) xx 4,
|
||||
(4, 11, 16, 23) xx 4,
|
||||
(6, 10, 15, 21) xx 4;
|
||||
|
||||
constant T = (floor(abs(sin($_ + 1)) * 2**32) for ^64);
|
||||
|
||||
constant k = flat ( $_ for ^16),
|
||||
((5*$_ + 1) % 16 for ^16),
|
||||
((3*$_ + 5) % 16 for ^16),
|
||||
((7*$_ ) % 16 for ^16);
|
||||
((5*$_ + 1) % 16 for ^16),
|
||||
((3*$_ + 5) % 16 for ^16),
|
||||
((7*$_ ) % 16 for ^16);
|
||||
|
||||
sub little-endian($w, $n, *@v) {
|
||||
my \step1 = ($w X* ^$n).eager; # temporary bug workaround
|
||||
|
|
@ -34,25 +31,24 @@ sub md5-pad(Blob $msg)
|
|||
flat @padded.map({ :256[$^d,$^c,$^b,$^a] }), little-endian(32, 2, bits);
|
||||
}
|
||||
|
||||
sub md5-block(@H is rw, @X)
|
||||
sub md5-block(@H, @X)
|
||||
{
|
||||
my ($A, $B, $C, $D) = @H;
|
||||
for ^64 -> \i {
|
||||
my \f = FGHI[i div 16]($B, $C, $D);
|
||||
($A, $B, $C, $D)
|
||||
= ($D, $B ⊞ (($A ⊞ f ⊞ T[i] ⊞ @X[k[i]]) <<< S[i]), $B, $C);
|
||||
}
|
||||
my uint32 ($A, $B, $C, $D) = @H;
|
||||
($A, $B, $C, $D) = ($D, $B ⊞ (($A ⊞ FGHI[$_ div 16]($B, $C, $D) ⊞ T[$_] ⊞ @X[k[$_]]) <<< _S[$_]), $B, $C) for ^64;
|
||||
@H «⊞=» ($A, $B, $C, $D);
|
||||
}
|
||||
|
||||
sub md5(Blob $msg --> Blob)
|
||||
{
|
||||
my @M = md5-pad($msg);
|
||||
my @H = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;
|
||||
my uint32 @M = md5-pad($msg);
|
||||
my uint32 @H = 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476;
|
||||
md5-block(@H, @M[$_ .. $_+15]) for 0, 16 ...^ +@M;
|
||||
Blob.new: little-endian(8, 4, @H);
|
||||
}
|
||||
|
||||
use Test;
|
||||
plan 7;
|
||||
|
||||
for 'd41d8cd98f00b204e9800998ecf8427e', '',
|
||||
'0cc175b9c0f1b6a831c399e269772661', 'a',
|
||||
'900150983cd24fb0d6963f7d28e17f72', 'abc',
|
||||
|
|
|
|||
164
Task/MD5-Implementation/Perl/md5-implementation.pl
Normal file
164
Task/MD5-Implementation/Perl/md5-implementation.pl
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use integer;
|
||||
use Test::More;
|
||||
|
||||
BEGIN { plan tests => 7 }
|
||||
|
||||
sub A() { 0x67_45_23_01 }
|
||||
sub B() { 0xef_cd_ab_89 }
|
||||
sub C() { 0x98_ba_dc_fe }
|
||||
sub D() { 0x10_32_54_76 }
|
||||
sub MAX() { 0xFFFFFFFF }
|
||||
|
||||
sub padding {
|
||||
my $l = length (my $msg = shift() . chr(128));
|
||||
$msg .= "\0" x (($l%64<=56?56:120)-$l%64);
|
||||
$l = ($l-1)*8;
|
||||
$msg .= pack 'VV', $l & MAX , ($l >> 16 >> 16);
|
||||
}
|
||||
|
||||
sub rotate_left($$) {
|
||||
($_[0] << $_[1]) | (( $_[0] >> (32 - $_[1]) ) & ((1 << $_[1]) - 1));
|
||||
}
|
||||
|
||||
sub gen_code {
|
||||
# Discard upper 32 bits on 64 bit archs.
|
||||
my $MSK = ((1 << 16) << 16) ? ' & ' . MAX : '';
|
||||
my %f = (
|
||||
FF => "X0=rotate_left((X3^(X1&(X2^X3)))+X0+X4+X6$MSK,X5)+X1$MSK;",
|
||||
GG => "X0=rotate_left((X2^(X3&(X1^X2)))+X0+X4+X6$MSK,X5)+X1$MSK;",
|
||||
HH => "X0=rotate_left((X1^X2^X3)+X0+X4+X6$MSK,X5)+X1$MSK;",
|
||||
II => "X0=rotate_left((X2^(X1|(~X3)))+X0+X4+X6$MSK,X5)+X1$MSK;",
|
||||
);
|
||||
|
||||
my %s = ( # shift lengths
|
||||
S11 => 7, S12 => 12, S13 => 17, S14 => 22, S21 => 5, S22 => 9, S23 => 14,
|
||||
S24 => 20, S31 => 4, S32 => 11, S33 => 16, S34 => 23, S41 => 6, S42 => 10,
|
||||
S43 => 15, S44 => 21
|
||||
);
|
||||
|
||||
my $insert = "\n";
|
||||
while(defined( my $data = <DATA> )) {
|
||||
chomp $data;
|
||||
next unless $data =~ /^[FGHI]/;
|
||||
my ($func,@x) = split /,/, $data;
|
||||
my $c = $f{$func};
|
||||
$c =~ s/X(\d)/$x[$1]/g;
|
||||
$c =~ s/(S\d{2})/$s{$1}/;
|
||||
$c =~ s/^(.*)=rotate_left\((.*),(.*)\)\+(.*)$//;
|
||||
|
||||
my $su = 32 - $3;
|
||||
my $sh = (1 << $3) - 1;
|
||||
|
||||
$c = "$1=(((\$r=$2)<<$3)|((\$r>>$su)&$sh))+$4";
|
||||
|
||||
$insert .= "\t$c\n";
|
||||
}
|
||||
close DATA;
|
||||
|
||||
my $dump = '
|
||||
sub round {
|
||||
my ($a,$b,$c,$d) = @_[0 .. 3];
|
||||
my $r;' . $insert . '
|
||||
$_[0]+$a' . $MSK . ', $_[1]+$b ' . $MSK .
|
||||
', $_[2]+$c' . $MSK . ', $_[3]+$d' . $MSK . ';
|
||||
}';
|
||||
eval $dump;
|
||||
}
|
||||
|
||||
gen_code();
|
||||
|
||||
sub _encode_hex { unpack 'H*', $_[0] }
|
||||
|
||||
sub md5 {
|
||||
my $message = padding(join'',@_);
|
||||
my ($a,$b,$c,$d) = (A,B,C,D);
|
||||
my $i;
|
||||
for $i (0 .. (length $message)/64-1) {
|
||||
my @X = unpack 'V16', substr $message,$i*64,64;
|
||||
($a,$b,$c,$d) = round($a,$b,$c,$d,@X);
|
||||
}
|
||||
pack 'V4',$a,$b,$c,$d;
|
||||
}
|
||||
|
||||
my $strings = {
|
||||
'd41d8cd98f00b204e9800998ecf8427e' => '',
|
||||
'0cc175b9c0f1b6a831c399e269772661' => 'a',
|
||||
'900150983cd24fb0d6963f7d28e17f72' => 'abc',
|
||||
'f96b697d7cb7938d525a2f31aaf161d0' => 'message digest',
|
||||
'c3fcd3d76192e4007dfb496cca67e13b' => 'abcdefghijklmnopqrstuvwxyz',
|
||||
'd174ab98d277d9f5a5611c2c9f419d9f' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
|
||||
'57edf4a22be3c955ac49da2e2107b67a' => '12345678901234567890123456789012345678901234567890123456789012345678901234567890',
|
||||
};
|
||||
|
||||
for my $k (keys %$strings) {
|
||||
my $digest = _encode_hex md5($strings->{$k});
|
||||
is($digest, $k, "$digest is MD5 digest $strings->{$k}");
|
||||
}
|
||||
|
||||
__DATA__
|
||||
FF,$a,$b,$c,$d,$_[4],7,0xd76aa478,/* 1 */
|
||||
FF,$d,$a,$b,$c,$_[5],12,0xe8c7b756,/* 2 */
|
||||
FF,$c,$d,$a,$b,$_[6],17,0x242070db,/* 3 */
|
||||
FF,$b,$c,$d,$a,$_[7],22,0xc1bdceee,/* 4 */
|
||||
FF,$a,$b,$c,$d,$_[8],7,0xf57c0faf,/* 5 */
|
||||
FF,$d,$a,$b,$c,$_[9],12,0x4787c62a,/* 6 */
|
||||
FF,$c,$d,$a,$b,$_[10],17,0xa8304613,/* 7 */
|
||||
FF,$b,$c,$d,$a,$_[11],22,0xfd469501,/* 8 */
|
||||
FF,$a,$b,$c,$d,$_[12],7,0x698098d8,/* 9 */
|
||||
FF,$d,$a,$b,$c,$_[13],12,0x8b44f7af,/* 10 */
|
||||
FF,$c,$d,$a,$b,$_[14],17,0xffff5bb1,/* 11 */
|
||||
FF,$b,$c,$d,$a,$_[15],22,0x895cd7be,/* 12 */
|
||||
FF,$a,$b,$c,$d,$_[16],7,0x6b901122,/* 13 */
|
||||
FF,$d,$a,$b,$c,$_[17],12,0xfd987193,/* 14 */
|
||||
FF,$c,$d,$a,$b,$_[18],17,0xa679438e,/* 15 */
|
||||
FF,$b,$c,$d,$a,$_[19],22,0x49b40821,/* 16 */
|
||||
GG,$a,$b,$c,$d,$_[5],5,0xf61e2562,/* 17 */
|
||||
GG,$d,$a,$b,$c,$_[10],9,0xc040b340,/* 18 */
|
||||
GG,$c,$d,$a,$b,$_[15],14,0x265e5a51,/* 19 */
|
||||
GG,$b,$c,$d,$a,$_[4],20,0xe9b6c7aa,/* 20 */
|
||||
GG,$a,$b,$c,$d,$_[9],5,0xd62f105d,/* 21 */
|
||||
GG,$d,$a,$b,$c,$_[14],9,0x2441453,/* 22 */
|
||||
GG,$c,$d,$a,$b,$_[19],14,0xd8a1e681,/* 23 */
|
||||
GG,$b,$c,$d,$a,$_[8],20,0xe7d3fbc8,/* 24 */
|
||||
GG,$a,$b,$c,$d,$_[13],5,0x21e1cde6,/* 25 */
|
||||
GG,$d,$a,$b,$c,$_[18],9,0xc33707d6,/* 26 */
|
||||
GG,$c,$d,$a,$b,$_[7],14,0xf4d50d87,/* 27 */
|
||||
GG,$b,$c,$d,$a,$_[12],20,0x455a14ed,/* 28 */
|
||||
GG,$a,$b,$c,$d,$_[17],5,0xa9e3e905,/* 29 */
|
||||
GG,$d,$a,$b,$c,$_[6],9,0xfcefa3f8,/* 30 */
|
||||
GG,$c,$d,$a,$b,$_[11],14,0x676f02d9,/* 31 */
|
||||
GG,$b,$c,$d,$a,$_[16],20,0x8d2a4c8a,/* 32 */
|
||||
HH,$a,$b,$c,$d,$_[9],4,0xfffa3942,/* 33 */
|
||||
HH,$d,$a,$b,$c,$_[12],11,0x8771f681,/* 34 */
|
||||
HH,$c,$d,$a,$b,$_[15],16,0x6d9d6122,/* 35 */
|
||||
HH,$b,$c,$d,$a,$_[18],23,0xfde5380c,/* 36 */
|
||||
HH,$a,$b,$c,$d,$_[5],4,0xa4beea44,/* 37 */
|
||||
HH,$d,$a,$b,$c,$_[8],11,0x4bdecfa9,/* 38 */
|
||||
HH,$c,$d,$a,$b,$_[11],16,0xf6bb4b60,/* 39 */
|
||||
HH,$b,$c,$d,$a,$_[14],23,0xbebfbc70,/* 40 */
|
||||
HH,$a,$b,$c,$d,$_[17],4,0x289b7ec6,/* 41 */
|
||||
HH,$d,$a,$b,$c,$_[4],11,0xeaa127fa,/* 42 */
|
||||
HH,$c,$d,$a,$b,$_[7],16,0xd4ef3085,/* 43 */
|
||||
HH,$b,$c,$d,$a,$_[10],23,0x4881d05,/* 44 */
|
||||
HH,$a,$b,$c,$d,$_[13],4,0xd9d4d039,/* 45 */
|
||||
HH,$d,$a,$b,$c,$_[16],11,0xe6db99e5,/* 46 */
|
||||
HH,$c,$d,$a,$b,$_[19],16,0x1fa27cf8,/* 47 */
|
||||
HH,$b,$c,$d,$a,$_[6],23,0xc4ac5665,/* 48 */
|
||||
II,$a,$b,$c,$d,$_[4],6,0xf4292244,/* 49 */
|
||||
II,$d,$a,$b,$c,$_[11],10,0x432aff97,/* 50 */
|
||||
II,$c,$d,$a,$b,$_[18],15,0xab9423a7,/* 51 */
|
||||
II,$b,$c,$d,$a,$_[9],21,0xfc93a039,/* 52 */
|
||||
II,$a,$b,$c,$d,$_[16],6,0x655b59c3,/* 53 */
|
||||
II,$d,$a,$b,$c,$_[7],10,0x8f0ccc92,/* 54 */
|
||||
II,$c,$d,$a,$b,$_[14],15,0xffeff47d,/* 55 */
|
||||
II,$b,$c,$d,$a,$_[5],21,0x85845dd1,/* 56 */
|
||||
II,$a,$b,$c,$d,$_[12],6,0x6fa87e4f,/* 57 */
|
||||
II,$d,$a,$b,$c,$_[19],10,0xfe2ce6e0,/* 58 */
|
||||
II,$c,$d,$a,$b,$_[10],15,0xa3014314,/* 59 */
|
||||
II,$b,$c,$d,$a,$_[17],21,0x4e0811a1,/* 60 */
|
||||
II,$a,$b,$c,$d,$_[8],6,0xf7537e82,/* 61 */
|
||||
II,$d,$a,$b,$c,$_[15],10,0xbd3af235,/* 62 */
|
||||
II,$c,$d,$a,$b,$_[6],15,0x2ad7d2bb,/* 63 */
|
||||
II,$b,$c,$d,$a,$_[13],21,0xeb86d391,/* 64 */
|
||||
|
|
@ -1,124 +1,115 @@
|
|||
/*REXX program to test the MD5 procedure as per the test suite in the */
|
||||
/* IETF RFC (1321) ─── The MD5 Message─Digest Algorithm. April 1992. */
|
||||
/*REXX program tests the MD5 procedure (below) as per a test suite the IETF RFC (1321).*/
|
||||
msg.1 = /*─────MD5 test suite [from above doc].*/
|
||||
msg.2 = 'a'
|
||||
msg.3 = 'abc'
|
||||
msg.4 = 'message digest'
|
||||
msg.5 = 'abcdefghijklmnopqrstuvwxyz'
|
||||
msg.6 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||
msg.7 = 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
msg.0 = 7 /* [↑] last value doesn't need quotes.*/
|
||||
do m=1 for msg.0; say /*process each of the seven messages. */
|
||||
say ' in =' msg.m /*display the in message. */
|
||||
say 'out =' MD5(msg.m) /* " " out " */
|
||||
end /*m*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
MD5: procedure; parse arg !; numeric digits 20 /*insure there's enough decimal digits.*/
|
||||
a='67452301'x; b="efcdab89"x; c='98badcfe'x; d="10325476"x; x00='0'x; x80="80"x
|
||||
#=length(!) /*length in bytes of the input message.*/
|
||||
L=#*8//512; if L<448 then plus=448-L /*is the length less than 448 ? */
|
||||
if L>448 then plus=960-L /* " " " greater " " */
|
||||
if L=448 then plus=512 /* " " " equal to " */
|
||||
x00000000='00000000'x /* [↓] a little of this, ··· */
|
||||
$=! || x80 || copies( x00, plus%8 -1 )reverse(right(d2c(8 * #), 4, x00)) || x00000000
|
||||
/* [↑] ··· and a little of that.*/
|
||||
do j=0 to length($)%64-1 /*process the message (lots of steps).*/
|
||||
a_=a; b_=b; c_=c; d_=d /*save the original values for later.*/
|
||||
chunk=j*64 /*calculate the size of the chunks. */
|
||||
do k=1 for 16 /*process the message in chunks. */
|
||||
!.k=reverse( substr($, chunk + 1 + 4*(k-1), 4) ) /*magic stuff.*/
|
||||
end /*k*/
|
||||
|
||||
/*─────────────────────────────────────Md5 test suite (from above doc). */
|
||||
msg.1=''
|
||||
msg.2='a'
|
||||
msg.3='abc'
|
||||
msg.4='message digest'
|
||||
msg.5='abcdefghijklmnopqrstuvwxyz'
|
||||
msg.6='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||
msg.7='12345678901234567890123456789012345678901234567890123456789012345678901234567890'
|
||||
msg.0=7
|
||||
do m=1 for msg.0
|
||||
say ' in =' msg.m
|
||||
say 'out =' MD5(msg.m)
|
||||
say
|
||||
end /*m*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────MD5 subroutine──────────────────────*/
|
||||
MD5: procedure; parse arg !; numeric digits 20 /*insure enough digits.*/
|
||||
parse value '67452301'x 'efcdab89'x '98badcfe'x '10325476'x with a b c d
|
||||
#=length(!)
|
||||
L=#*8 // 512
|
||||
select
|
||||
when L<448 then plus=448-L
|
||||
when L>448 then plus=960-L
|
||||
when L=448 then plus=512
|
||||
end /*select*/
|
||||
a = .part1( a, b, c, d, 0, 7, 3614090360) /*■■■■ 1 ■■■■*/
|
||||
d = .part1( d, a, b, c, 1, 12, 3905402710) /*■■■■ 2 ■■■■*/
|
||||
c = .part1( c, d, a, b, 2, 17, 606105819) /*■■■■ 3 ■■■■*/
|
||||
b = .part1( b, c, d, a, 3, 22, 3250441966) /*■■■■ 4 ■■■■*/
|
||||
a = .part1( a, b, c, d, 4, 7, 4118548399) /*■■■■ 5 ■■■■*/
|
||||
d = .part1( d, a, b, c, 5, 12, 1200080426) /*■■■■ 6 ■■■■*/
|
||||
c = .part1( c, d, a, b, 6, 17, 2821735955) /*■■■■ 7 ■■■■*/
|
||||
b = .part1( b, c, d, a, 7, 22, 4249261313) /*■■■■ 8 ■■■■*/
|
||||
a = .part1( a, b, c, d, 8, 7, 1770035416) /*■■■■ 9 ■■■■*/
|
||||
d = .part1( d, a, b, c, 9, 12, 2336552879) /*■■■■ 10 ■■■■*/
|
||||
c = .part1( c, d, a, b, 10, 17, 4294925233) /*■■■■ 11 ■■■■*/
|
||||
b = .part1( b, c, d, a, 11, 22, 2304563134) /*■■■■ 12 ■■■■*/
|
||||
a = .part1( a, b, c, d, 12, 7, 1804603682) /*■■■■ 13 ■■■■*/
|
||||
d = .part1( d, a, b, c, 13, 12, 4254626195) /*■■■■ 14 ■■■■*/
|
||||
c = .part1( c, d, a, b, 14, 17, 2792965006) /*■■■■ 15 ■■■■*/
|
||||
b = .part1( b, c, d, a, 15, 22, 1236535329) /*■■■■ 16 ■■■■*/
|
||||
a = .part2( a, b, c, d, 1, 5, 4129170786) /*■■■■ 17 ■■■■*/
|
||||
d = .part2( d, a, b, c, 6, 9, 3225465664) /*■■■■ 18 ■■■■*/
|
||||
c = .part2( c, d, a, b, 11, 14, 643717713) /*■■■■ 19 ■■■■*/
|
||||
b = .part2( b, c, d, a, 0, 20, 3921069994) /*■■■■ 20 ■■■■*/
|
||||
a = .part2( a, b, c, d, 5, 5, 3593408605) /*■■■■ 21 ■■■■*/
|
||||
d = .part2( d, a, b, c, 10, 9, 38016083) /*■■■■ 22 ■■■■*/
|
||||
c = .part2( c, d, a, b, 15, 14, 3634488961) /*■■■■ 23 ■■■■*/
|
||||
b = .part2( b, c, d, a, 4, 20, 3889429448) /*■■■■ 24 ■■■■*/
|
||||
a = .part2( a, b, c, d, 9, 5, 568446438) /*■■■■ 25 ■■■■*/
|
||||
d = .part2( d, a, b, c, 14, 9, 3275163606) /*■■■■ 26 ■■■■*/
|
||||
c = .part2( c, d, a, b, 3, 14, 4107603335) /*■■■■ 27 ■■■■*/
|
||||
b = .part2( b, c, d, a, 8, 20, 1163531501) /*■■■■ 28 ■■■■*/
|
||||
a = .part2( a, b, c, d, 13, 5, 2850285829) /*■■■■ 29 ■■■■*/
|
||||
d = .part2( d, a, b, c, 2, 9, 4243563512) /*■■■■ 30 ■■■■*/
|
||||
c = .part2( c, d, a, b, 7, 14, 1735328473) /*■■■■ 31 ■■■■*/
|
||||
b = .part2( b, c, d, a, 12, 20, 2368359562) /*■■■■ 32 ■■■■*/
|
||||
a = .part3( a, b, c, d, 5, 4, 4294588738) /*■■■■ 33 ■■■■*/
|
||||
d = .part3( d, a, b, c, 8, 11, 2272392833) /*■■■■ 34 ■■■■*/
|
||||
c = .part3( c, d, a, b, 11, 16, 1839030562) /*■■■■ 35 ■■■■*/
|
||||
b = .part3( b, c, d, a, 14, 23, 4259657740) /*■■■■ 36 ■■■■*/
|
||||
a = .part3( a, b, c, d, 1, 4, 2763975236) /*■■■■ 37 ■■■■*/
|
||||
d = .part3( d, a, b, c, 4, 11, 1272893353) /*■■■■ 38 ■■■■*/
|
||||
c = .part3( c, d, a, b, 7, 16, 4139469664) /*■■■■ 39 ■■■■*/
|
||||
b = .part3( b, c, d, a, 10, 23, 3200236656) /*■■■■ 40 ■■■■*/
|
||||
a = .part3( a, b, c, d, 13, 4, 681279174) /*■■■■ 41 ■■■■*/
|
||||
d = .part3( d, a, b, c, 0, 11, 3936430074) /*■■■■ 42 ■■■■*/
|
||||
c = .part3( c, d, a, b, 3, 16, 3572445317) /*■■■■ 43 ■■■■*/
|
||||
b = .part3( b, c, d, a, 6, 23, 76029189) /*■■■■ 44 ■■■■*/
|
||||
a = .part3( a, b, c, d, 9, 4, 3654602809) /*■■■■ 45 ■■■■*/
|
||||
d = .part3( d, a, b, c, 12, 11, 3873151461) /*■■■■ 46 ■■■■*/
|
||||
c = .part3( c, d, a, b, 15, 16, 530742520) /*■■■■ 47 ■■■■*/
|
||||
b = .part3( b, c, d, a, 2, 23, 3299628645) /*■■■■ 48 ■■■■*/
|
||||
a = .part4( a, b, c, d, 0, 6, 4096336452) /*■■■■ 49 ■■■■*/
|
||||
d = .part4( d, a, b, c, 7, 10, 1126891415) /*■■■■ 50 ■■■■*/
|
||||
c = .part4( c, d, a, b, 14, 15, 2878612391) /*■■■■ 51 ■■■■*/
|
||||
b = .part4( b, c, d, a, 5, 21, 4237533241) /*■■■■ 52 ■■■■*/
|
||||
a = .part4( a, b, c, d, 12, 6, 1700485571) /*■■■■ 53 ■■■■*/
|
||||
d = .part4( d, a, b, c, 3, 10, 2399980690) /*■■■■ 54 ■■■■*/
|
||||
c = .part4( c, d, a, b, 10, 15, 4293915773) /*■■■■ 55 ■■■■*/
|
||||
b = .part4( b, c, d, a, 1, 21, 2240044497) /*■■■■ 56 ■■■■*/
|
||||
a = .part4( a, b, c, d, 8, 6, 1873313359) /*■■■■ 57 ■■■■*/
|
||||
d = .part4( d, a, b, c, 15, 10, 4264355552) /*■■■■ 58 ■■■■*/
|
||||
c = .part4( c, d, a, b, 6, 15, 2734768916) /*■■■■ 59 ■■■■*/
|
||||
b = .part4( b, c, d, a, 13, 21, 1309151649) /*■■■■ 60 ■■■■*/
|
||||
a = .part4( a, b, c, d, 4, 6, 4149444226) /*■■■■ 61 ■■■■*/
|
||||
d = .part4( d, a, b, c, 11, 10, 3174756917) /*■■■■ 62 ■■■■*/
|
||||
c = .part4( c, d, a, b, 2, 15, 718787259) /*■■■■ 63 ■■■■*/
|
||||
b = .part4( b, c, d, a, 9, 21, 3951481745) /*■■■■ 64 ■■■■*/
|
||||
a = .a(a_,a); b=.a(b_,b); c=.a(c_,c); d=.a(d_,d)
|
||||
end /*j*/
|
||||
|
||||
$=!||'80'x||copies('0'x,plus%8-1)reverse(right(d2c(8*#),4,'0'x))||'00000000'x
|
||||
|
||||
do j=0 to length($)%64-1 /*process message (lots of steps)*/
|
||||
a_=a; b_=b; c_=c; d_=d
|
||||
chunk=j*64
|
||||
do k=1 for 16 /*process the message in chunks. */
|
||||
!.k=reverse(substr($,chunk+1+4*(k-1),4))
|
||||
end /*k*/
|
||||
|
||||
a=.part1(a,b,c,d, 0, 7,3614090360) /* 1*/
|
||||
d=.part1(d,a,b,c, 1,12,3905402710) /* 2*/
|
||||
c=.part1(c,d,a,b, 2,17, 606105819) /* 3*/
|
||||
b=.part1(b,c,d,a, 3,22,3250441966) /* 4*/
|
||||
a=.part1(a,b,c,d, 4, 7,4118548399) /* 5*/
|
||||
d=.part1(d,a,b,c, 5,12,1200080426) /* 6*/
|
||||
c=.part1(c,d,a,b, 6,17,2821735955) /* 7*/
|
||||
b=.part1(b,c,d,a, 7,22,4249261313) /* 8*/
|
||||
a=.part1(a,b,c,d, 8, 7,1770035416) /* 9*/
|
||||
d=.part1(d,a,b,c, 9,12,2336552879) /*10*/
|
||||
c=.part1(c,d,a,b,10,17,4294925233) /*11*/
|
||||
b=.part1(b,c,d,a,11,22,2304563134) /*12*/
|
||||
a=.part1(a,b,c,d,12, 7,1804603682) /*13*/
|
||||
d=.part1(d,a,b,c,13,12,4254626195) /*14*/
|
||||
c=.part1(c,d,a,b,14,17,2792965006) /*15*/
|
||||
b=.part1(b,c,d,a,15,22,1236535329) /*16*/
|
||||
a=.part2(a,b,c,d, 1, 5,4129170786) /*17*/
|
||||
d=.part2(d,a,b,c, 6, 9,3225465664) /*18*/
|
||||
c=.part2(c,d,a,b,11,14, 643717713) /*19*/
|
||||
b=.part2(b,c,d,a, 0,20,3921069994) /*20*/
|
||||
a=.part2(a,b,c,d, 5, 5,3593408605) /*21*/
|
||||
d=.part2(d,a,b,c,10, 9, 38016083) /*22*/
|
||||
c=.part2(c,d,a,b,15,14,3634488961) /*23*/
|
||||
b=.part2(b,c,d,a, 4,20,3889429448) /*24*/
|
||||
a=.part2(a,b,c,d, 9, 5, 568446438) /*25*/
|
||||
d=.part2(d,a,b,c,14, 9,3275163606) /*26*/
|
||||
c=.part2(c,d,a,b, 3,14,4107603335) /*27*/
|
||||
b=.part2(b,c,d,a, 8,20,1163531501) /*28*/
|
||||
a=.part2(a,b,c,d,13, 5,2850285829) /*29*/
|
||||
d=.part2(d,a,b,c, 2, 9,4243563512) /*30*/
|
||||
c=.part2(c,d,a,b, 7,14,1735328473) /*31*/
|
||||
b=.part2(b,c,d,a,12,20,2368359562) /*32*/
|
||||
a=.part3(a,b,c,d, 5, 4,4294588738) /*33*/
|
||||
d=.part3(d,a,b,c, 8,11,2272392833) /*34*/
|
||||
c=.part3(c,d,a,b,11,16,1839030562) /*35*/
|
||||
b=.part3(b,c,d,a,14,23,4259657740) /*36*/
|
||||
a=.part3(a,b,c,d, 1, 4,2763975236) /*37*/
|
||||
d=.part3(d,a,b,c, 4,11,1272893353) /*38*/
|
||||
c=.part3(c,d,a,b, 7,16,4139469664) /*39*/
|
||||
b=.part3(b,c,d,a,10,23,3200236656) /*40*/
|
||||
a=.part3(a,b,c,d,13, 4, 681279174) /*41*/
|
||||
d=.part3(d,a,b,c, 0,11,3936430074) /*42*/
|
||||
c=.part3(c,d,a,b, 3,16,3572445317) /*43*/
|
||||
b=.part3(b,c,d,a, 6,23, 76029189) /*44*/
|
||||
a=.part3(a,b,c,d, 9, 4,3654602809) /*45*/
|
||||
d=.part3(d,a,b,c,12,11,3873151461) /*46*/
|
||||
c=.part3(c,d,a,b,15,16, 530742520) /*47*/
|
||||
b=.part3(b,c,d,a, 2,23,3299628645) /*48*/
|
||||
a=.part4(a,b,c,d, 0, 6,4096336452) /*49*/
|
||||
d=.part4(d,a,b,c, 7,10,1126891415) /*50*/
|
||||
c=.part4(c,d,a,b,14,15,2878612391) /*51*/
|
||||
b=.part4(b,c,d,a, 5,21,4237533241) /*52*/
|
||||
a=.part4(a,b,c,d,12, 6,1700485571) /*53*/
|
||||
d=.part4(d,a,b,c, 3,10,2399980690) /*54*/
|
||||
c=.part4(c,d,a,b,10,15,4293915773) /*55*/
|
||||
b=.part4(b,c,d,a, 1,21,2240044497) /*56*/
|
||||
a=.part4(a,b,c,d, 8, 6,1873313359) /*57*/
|
||||
d=.part4(d,a,b,c,15,10,4264355552) /*58*/
|
||||
c=.part4(c,d,a,b, 6,15,2734768916) /*59*/
|
||||
b=.part4(b,c,d,a,13,21,1309151649) /*60*/
|
||||
a=.part4(a,b,c,d, 4, 6,4149444226) /*61*/
|
||||
d=.part4(d,a,b,c,11,10,3174756917) /*62*/
|
||||
c=.part4(c,d,a,b, 2,15, 718787259) /*63*/
|
||||
b=.part4(b,c,d,a, 9,21,3951481745) /*64*/
|
||||
a=.a(a_,a); b=.a(b_,b); c=.a(c_,c); d=.a(d_,d)
|
||||
end /*j*/
|
||||
|
||||
return c2x(reverse(a))c2x(reverse(b))c2x(reverse(c))c2x(reverse(d))
|
||||
/*─────────────────────────────────────subroutines──────────────────────*/
|
||||
.part1: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.lR(right(d2c(_+c2d(w)+c2d(.f(x,y,z))+c2d(!.n)),4,'0'x),m),x)
|
||||
.part2: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.lR(right(d2c(_+c2d(w)+c2d(.g(x,y,z))+c2d(!.n)),4,'0'x),m),x)
|
||||
.part3: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.lR(right(d2c(_+c2d(w)+c2d(.h(x,y,z))+c2d(!.n)),4,'0'x),m),x)
|
||||
.part4: procedure expose !.; parse arg w,x,y,z,n,m; n=n+1
|
||||
return .a(.lR(right(d2c(c2d(w)+c2d(.i(x,y,z))+c2d(!.n)+arg(7)),4,'0'x),m),x)
|
||||
.h: procedure; parse arg x,y,z; return bitxor(bitxor(x,y),z)
|
||||
.i: return bitxor(arg(2),bitor(arg(1),bitxor(arg(3),'ffffffff'x)))
|
||||
.a: return right(d2c(c2d(arg(1))+c2d(arg(2))),4,'0'x)
|
||||
.f: procedure; parse arg x,y,z
|
||||
return bitor(bitand(x,y),bitand(bitxor(x,'ffffffff'x),z))
|
||||
.g: procedure; parse arg x,y,z
|
||||
return bitor(bitand(x,z),bitand(y,bitxor(z,'ffffffff'x)))
|
||||
.lR: procedure; parse arg _,#; if #==0 then return _ /*left rotate.*/
|
||||
?=x2b(c2x(_)); return x2c(b2x(right(?||left(?,#),length(?))))
|
||||
return c2x( reverse(a) )c2x( reverse(b) )c2x( reverse(c) )c2x( reverse(d) )
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
.a: return right(d2c(c2d(arg(1)) + c2d(arg(2))), 4, '0'x)
|
||||
.h: return bitxor(bitxor(arg(1), arg(2)), arg(3))
|
||||
.i: return bitxor(arg(2), bitor(arg(1), bitxor(arg(3), 'ffffffff'x)))
|
||||
.f: return bitor(bitand(arg(1),arg(2)), bitand(bitxor(arg(1), 'ffffffff'x), arg(3)))
|
||||
.g: return bitor(bitand(arg(1),arg(3)), bitand(arg(2), bitxor(arg(3), 'ffffffff'x)))
|
||||
.Lr: procedure; parse arg _,#; if #==0 then return _ /*left rotate.*/
|
||||
?=x2b(c2x(_)); return x2c(b2x(right(? || left(?, #), length(?))))
|
||||
.part1: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.Lr(right(d2c(_+c2d(w)+c2d(.f(x,y,z))+c2d(!.n)),4,'0'x),m),x)
|
||||
.part2: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.Lr(right(d2c(_+c2d(w)+c2d(.g(x,y,z))+c2d(!.n)),4,'0'x),m),x)
|
||||
.part3: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.Lr(right(d2c(_+c2d(w)+c2d(.h(x,y,z))+c2d(!.n)),4,'0'x),m),x)
|
||||
.part4: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.Lr(right(d2c(c2d(w)+c2d(.i(x,y,z))+c2d(!.n)+_),4,'0'x),m),x)
|
||||
|
|
|
|||
243
Task/MD5-Implementation/RPG/md5-implementation.rpg
Normal file
243
Task/MD5-Implementation/RPG/md5-implementation.rpg
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
**FREE
|
||||
Ctl-opt MAIN(Main);
|
||||
Ctl-opt DFTACTGRP(*NO) ACTGRP(*NEW);
|
||||
|
||||
dcl-pr QDCXLATE EXTPGM('QDCXLATE');
|
||||
dataLen packed(5 : 0) CONST;
|
||||
data char(32767) options(*VARSIZE);
|
||||
conversionTable char(10) CONST;
|
||||
end-pr;
|
||||
|
||||
dcl-c MASK32 CONST(4294967295);
|
||||
dcl-s SHIFT_AMTS int(3) dim(16) CTDATA PERRCD(16);
|
||||
dcl-s MD5_TABLE_T int(20) dim(64) CTDATA PERRCD(4);
|
||||
|
||||
dcl-proc Main;
|
||||
dcl-s inputData char(45);
|
||||
dcl-s inputDataLen int(10) INZ(0);
|
||||
dcl-s outputHash char(16);
|
||||
dcl-s outputHashHex char(32);
|
||||
|
||||
DSPLY 'Input: ' '' inputData;
|
||||
inputData = %trim(inputData);
|
||||
inputDataLen = %len(%trim(inputData));
|
||||
DSPLY ('Input=' + inputData);
|
||||
DSPLY ('InputLen=' + %char(inputDataLen));
|
||||
|
||||
// Convert from EBCDIC to ASCII
|
||||
if inputDataLen > 0;
|
||||
QDCXLATE(inputDataLen : inputData : 'QTCPASC');
|
||||
endif;
|
||||
CalculateMD5(inputData : inputDataLen : outputHash);
|
||||
// Convert to hex
|
||||
ConvertToHex(outputHash : 16 : outputHashHex);
|
||||
DSPLY ('MD5: ' + outputHashHex);
|
||||
return;
|
||||
end-proc;
|
||||
|
||||
dcl-proc CalculateMD5;
|
||||
dcl-pi *N;
|
||||
message char(65535) options(*VARSIZE) CONST;
|
||||
messageLen int(10) value;
|
||||
outputHash char(16);
|
||||
end-pi;
|
||||
dcl-s numBlocks int(10);
|
||||
dcl-s padding char(72);
|
||||
dcl-s a int(20) INZ(1732584193);
|
||||
dcl-s b int(20) INZ(4023233417);
|
||||
dcl-s c int(20) INZ(2562383102);
|
||||
dcl-s d int(20) INZ(271733878);
|
||||
dcl-s buffer int(20) dim(16) INZ(0);
|
||||
dcl-s i int(10);
|
||||
dcl-s j int(10);
|
||||
dcl-s k int(10);
|
||||
dcl-s multiplier int(20);
|
||||
dcl-s index int(10);
|
||||
dcl-s originalA int(20);
|
||||
dcl-s originalB int(20);
|
||||
dcl-s originalC int(20);
|
||||
dcl-s originalD int(20);
|
||||
dcl-s div16 int(10);
|
||||
dcl-s f int(20);
|
||||
dcl-s tempInt int(20);
|
||||
dcl-s bufferIndex int(10);
|
||||
dcl-ds byteToInt QUALIFIED;
|
||||
n int(5) INZ(0);
|
||||
c char(1) OVERLAY(n : 2);
|
||||
end-ds;
|
||||
|
||||
numBlocks = (messageLen + 8) / 64 + 1;
|
||||
MD5_FillPadding(messageLen : numBlocks : padding);
|
||||
for i = 0 to numBlocks - 1;
|
||||
index = i * 64;
|
||||
|
||||
// Read message as little-endian 32-bit words
|
||||
for j = 1 to 16;
|
||||
multiplier = 1;
|
||||
for k = 1 to 4;
|
||||
index += 1;
|
||||
if index <= messageLen;
|
||||
byteToInt.c = %subst(message : index : 1);
|
||||
else;
|
||||
byteToInt.c = %subst(padding : index - messageLen : 1);
|
||||
endif;
|
||||
buffer(j) += multiplier * byteToInt.n;
|
||||
multiplier *= 256;
|
||||
endfor;
|
||||
endfor;
|
||||
|
||||
originalA = a;
|
||||
originalB = b;
|
||||
originalC = c;
|
||||
originalD = d;
|
||||
|
||||
for j = 0 to 63;
|
||||
div16 = j / 16;
|
||||
select;
|
||||
when div16 = 0;
|
||||
f = %bitor(%bitand(b : c) : %bitand(%bitnot(b) : d));
|
||||
bufferIndex = j;
|
||||
|
||||
when div16 = 1;
|
||||
f = %bitor(%bitand(b : d) : %bitand(c : %bitnot(d)));
|
||||
bufferIndex = %bitand(j * 5 + 1 : 15);
|
||||
|
||||
when div16 = 2;
|
||||
f = %bitxor(b : %bitxor(c : d));
|
||||
bufferIndex = %bitand(j * 3 + 5 : 15);
|
||||
|
||||
when div16 = 3;
|
||||
f = %bitxor(c : %bitor(b : Mask32Bit(%bitnot(d))));
|
||||
bufferIndex = %bitand(j * 7 : 15);
|
||||
endsl;
|
||||
tempInt = Mask32Bit(b + RotateLeft32Bit(a + f + buffer(bufferIndex + 1) + MD5_TABLE_T(j + 1) :
|
||||
SHIFT_AMTS(div16 * 4 + %bitand(j : 3) + 1)));
|
||||
a = d;
|
||||
d = c;
|
||||
c = b;
|
||||
b = tempInt;
|
||||
endfor;
|
||||
a = Mask32Bit(a + originalA);
|
||||
b = Mask32Bit(b + originalB);
|
||||
c = Mask32Bit(c + originalC);
|
||||
d = Mask32Bit(d + originalD);
|
||||
endfor;
|
||||
|
||||
for i = 0 to 3;
|
||||
if i = 0;
|
||||
tempInt = a;
|
||||
elseif i = 1;
|
||||
tempInt = b;
|
||||
elseif i = 2;
|
||||
tempInt = c;
|
||||
else;
|
||||
tempInt = d;
|
||||
endif;
|
||||
|
||||
for j = 0 to 3;
|
||||
byteToInt.n = %bitand(tempInt : 255);
|
||||
%subst(outputHash : i * 4 + j + 1 : 1) = byteToInt.c;
|
||||
tempInt /= 256;
|
||||
endfor;
|
||||
endfor;
|
||||
return;
|
||||
end-proc;
|
||||
|
||||
dcl-proc MD5_FillPadding;
|
||||
dcl-pi *N;
|
||||
messageLen int(10);
|
||||
numBlocks int(10);
|
||||
padding char(72);
|
||||
end-pi;
|
||||
dcl-s totalLen int(10);
|
||||
dcl-s paddingSize int(10);
|
||||
dcl-ds *N;
|
||||
messageLenBits int(20);
|
||||
mlb_bytes char(8) OVERLAY(messageLenBits);
|
||||
end-ds;
|
||||
dcl-s i int(10);
|
||||
|
||||
%subst(padding : 1 : 1) = X'80';
|
||||
totalLen = numBlocks * 64;
|
||||
paddingSize = totalLen - messageLen; // 9 to 72
|
||||
messageLenBits = messageLen;
|
||||
messageLenBits *= 8;
|
||||
for i = 1 to 8;
|
||||
%subst(padding : paddingSize - i + 1 : 1) = %subst(mlb_bytes : i : 1);
|
||||
endfor;
|
||||
for i = 2 to paddingSize - 8;
|
||||
%subst(padding : i : 1) = X'00';
|
||||
endfor;
|
||||
return;
|
||||
end-proc;
|
||||
|
||||
dcl-proc RotateLeft32Bit;
|
||||
dcl-pi *N int(20);
|
||||
n int(20) value;
|
||||
amount int(3) value;
|
||||
end-pi;
|
||||
dcl-s i int(3);
|
||||
|
||||
n = Mask32Bit(n);
|
||||
for i = 1 to amount;
|
||||
n *= 2;
|
||||
if n >= 4294967296;
|
||||
n -= MASK32;
|
||||
endif;
|
||||
endfor;
|
||||
return n;
|
||||
end-proc;
|
||||
|
||||
dcl-proc Mask32Bit;
|
||||
dcl-pi *N int(20);
|
||||
n int(20) value;
|
||||
end-pi;
|
||||
return %bitand(n : MASK32);
|
||||
end-proc;
|
||||
|
||||
dcl-proc ConvertToHex;
|
||||
dcl-pi *N;
|
||||
inputData char(32767) options(*VARSIZE) CONST;
|
||||
inputDataLen int(10) value;
|
||||
outputData char(65534) options(*VARSIZE);
|
||||
end-pi;
|
||||
dcl-c HEX_CHARS CONST('0123456789ABCDEF');
|
||||
dcl-s i int(10);
|
||||
dcl-s outputOffset int(10) INZ(1);
|
||||
dcl-ds dataStruct QUALIFIED;
|
||||
numField int(5) INZ(0);
|
||||
// IBM i is big-endian
|
||||
charField char(1) OVERLAY(numField : 2);
|
||||
end-ds;
|
||||
|
||||
for i = 1 to inputDataLen;
|
||||
dataStruct.charField = %BitAnd(%subst(inputData : i : 1) : X'F0');
|
||||
dataStruct.numField /= 16;
|
||||
%subst(outputData : outputOffset : 1) = %subst(HEX_CHARS : dataStruct.numField + 1 : 1);
|
||||
outputOffset += 1;
|
||||
dataStruct.charField = %BitAnd(%subst(inputData : i : 1) : X'0F');
|
||||
%subst(outputData : outputOffset : 1) = %subst(HEX_CHARS : dataStruct.numField + 1 : 1);
|
||||
outputOffset += 1;
|
||||
endfor;
|
||||
return;
|
||||
end-proc;
|
||||
|
||||
**CTDATA SHIFT_AMTS
|
||||
7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21
|
||||
**CTDATA MD5_TABLE_T
|
||||
3614090360 3905402710 606105819 3250441966
|
||||
4118548399 1200080426 2821735955 4249261313
|
||||
1770035416 2336552879 4294925233 2304563134
|
||||
1804603682 4254626195 2792965006 1236535329
|
||||
4129170786 3225465664 643717713 3921069994
|
||||
3593408605 38016083 3634488961 3889429448
|
||||
568446438 3275163606 4107603335 1163531501
|
||||
2850285829 4243563512 1735328473 2368359562
|
||||
4294588738 2272392833 1839030562 4259657740
|
||||
2763975236 1272893353 4139469664 3200236656
|
||||
681279174 3936430074 3572445317 76029189
|
||||
3654602809 3873151461 530742520 3299628645
|
||||
4096336452 1126891415 2878612391 4237533241
|
||||
1700485571 2399980690 4293915773 2240044497
|
||||
1873313359 4264355552 2734768916 1309151649
|
||||
4149444226 3174756917 718787259 3951481745
|
||||
Loading…
Add table
Add a link
Reference in a new issue