41 lines
1.4 KiB
APL
41 lines
1.4 KiB
APL
md5←{
|
||
⍝ index origin zero
|
||
⎕IO←0
|
||
⍝ decoding UTF-8 & padding
|
||
M←(⊢,(0⍴⍨512|448-512|≢))1,⍨l←,⍉(8⍴2)⊤'UTF-8'⎕UCS ⍵
|
||
⍝ add length
|
||
M,←,⍉(8⍴2)⊤⌽(8⍴256)⊤≢l
|
||
⍝ init registers
|
||
A←16⊥6 7 4 5 2 3 0 1
|
||
B←16⊥14 15 12 13 10 11 8 9
|
||
C←16⊥9 8 11 10 13 12 15 14
|
||
D←16⊥1 0 3 2 5 4 7 6
|
||
⍝ T table
|
||
T←⌊(2*32)×|1○1+⍳64
|
||
⍝ index table
|
||
K←16|i,(1+5×i),(5+3×i),7×i←⍳16
|
||
⍝ rot table
|
||
S←,1 0 2⍉4 4 4⍴7 12 17 22 5 9 14 20 4 11 16 23 6 10 15 21
|
||
⍝ truncate ⍵ to 32 bit & rot left ⍺
|
||
rot←{2⊥⍺⌽(32⍴2)⊤⍵}
|
||
proc←{
|
||
⍝ pack 512 bits into 32 bit words &
|
||
⍝ precompute X[k] + T[i]
|
||
l←T+(⊂K)⌷256⊥⍉⌽16 4⍴2⊥⍉64 8⍴⍺
|
||
fn←{
|
||
⍝ a b c d to binary
|
||
a b c d←↓⍉(32⍴2)⊤⍵
|
||
⍝ a + F(b,c,d)
|
||
⍺<16:S[⍺]rot l[⍺]+2⊥a+d≠b∧c≠d
|
||
⍺<32:S[⍺]rot l[⍺]+2⊥a+(b∧d)∨(c∧~d)
|
||
⍺<48:S[⍺]rot l[⍺]+2⊥a+b≠c≠d
|
||
S[⍺]rot l[⍺]+2⊥a+c≠b∨~d
|
||
}
|
||
(2*32)|⍵+⊃{¯1⌽((⍵[1]+⍺ fn ⍵)@0)⍵}/(⌽⍳64),⊂⍵
|
||
}
|
||
⍝ process each 512 bits
|
||
loop←{⍬≡⍺:⍵ ⋄ (512↓⍺)∇(512↑⍺)proc ⍵}
|
||
⍝ output registers
|
||
(⎕D,⎕A)[,⍉(2⍴16)⊤,⍉⊖(4⍴256)⊤M loop A B C D]
|
||
}
|