MD4: Difference between revisions

Content added Content deleted
m (→‎{{header|Perl}}: future-proof for 5.36, explicit :prototype)
(Dialects of BASIC moved to the BASIC section.)
Line 105: Line 105:
<pre>String: Rosetta Code
<pre>String: Rosetta Code
MD4: A52BCFC6A0D0D300CDC5DDBFBEFE478B</pre>
MD4: A52BCFC6A0D0D300CDC5DDBFBEFE478B</pre>

=={{header|BASIC}}==
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">' version 19-10-2016
' translation of the (pseudo) code in RFC 1320
' compile with: fbc -s console

Function MD4(test_str As String) As String
Dim As String message = test_str ' string are passed as ByRef

' some macro's
#Macro F(X, Y, Z)
(((X) And (Y)) Or ((Not(X)) And (Z)))
#EndMacro

#Macro G(X, Y, Z)
(((X) And (Y)) Or (((X) And (Z)) Or ((Y) And (Z))))
#EndMacro

#Macro H(X, Y, Z)
((X) Xor (Y) Xor (Z))
#EndMacro
' a little piece of inline asm to do a rotate left on a 32bit variable
#Macro ROtate_Left(x, n) ' rotate left
Asm
rol dword Ptr [x], n
End Asm
#EndMacro
' #Macro ROtate_left(x, n)
' x = x Shl n + x Shr (32 - n)
' #EndMacro
Dim As Long i
Dim As String answer, s1

Dim As ULongInt l = Len(message)
' set the first bit after the message to 1
message = message + Chr(1 Shl 7)
' add one char to the length
Dim As ULong padding = 64 - ((l +1) Mod (512 \ 8)) ' 512 \ 8 = 64 char.

' check if we have enough room for inserting the length
If padding < 8 Then padding = padding + 64

message = message + String(padding, Chr(0)) ' adjust length
Dim As ULong l1 = Len(message) ' new length

l = l * 8 ' orignal length in bits
' create ubyte ptr to point to l ( = length in bits)
Dim As UByte Ptr ub_ptr = Cast(UByte Ptr, @l)

For i = 0 To 7 'copy length of message to the last 8 bytes
message[l1 -8 + i] = ub_ptr[i]
Next

' unsigned 32bit integers only
Dim As UInteger<32> AA, A = &H67452301
Dim As UInteger<32> BB, B = &Hefcdab89
Dim As UInteger<32> CC, C = &H98badcfe
Dim As UInteger<32> DD, D = &H10325476

For i = 0 To (l1 -1) \ 64 ' split into 64 byte block

AA = A : BB = B : CC = C : DD = D

' x point to 64 byte block inside the string message
Dim As UInteger<32> Ptr x = Cast(UInteger<32> Ptr, @message[i*64])

' round 1
A = A + F(B, C, D) + x[ 0] : ROtate_Left(A, 3)
D = D + F(A, B, C) + x[ 1] : ROtate_Left(D, 7)
C = C + F(D, A, B) + x[ 2] : ROtate_Left(C, 11)
B = B + F(C, D, A) + x[ 3] : ROtate_Left(B, 19)
A = A + F(B, C, D) + x[ 4] : ROtate_Left(A, 3)
D = D + F(A, B, C) + x[ 5] : ROtate_Left(D, 7)
C = C + F(D, A, B) + x[ 6] : ROtate_Left(C, 11)
B = B + F(C, D, A) + x[ 7] : ROtate_Left(B, 19)
A = A + F(B, C, D) + x[ 8] : ROtate_Left(A, 3)
D = D + F(A, B, C) + x[ 9] : ROtate_Left(D, 7)
C = C + F(D, A, B) + x[10] : ROtate_Left(C, 11)
B = B + F(C, D, A) + x[11] : ROtate_Left(B, 19)
A = A + F(B, C, D) + x[12] : ROtate_Left(A, 3)
D = D + F(A, B, C) + x[13] : ROtate_Left(D, 7)
C = C + F(D, A, B) + x[14] : ROtate_Left(C, 11)
B = B + F(C, D, A) + x[15] : ROtate_Left(B, 19)

' round 2
A = A + G(B, C, D) + x[ 0] + &H5A827999 : ROtate_Left(A, 3)
D = D + G(A, B, C) + x[ 4] + &H5A827999 : ROtate_Left(D, 5)
C = C + G(D, A, B) + x[ 8] + &H5A827999 : ROtate_Left(C, 9)
B = B + G(C, D, A) + x[12] + &H5A827999 : ROtate_Left(B, 13)
A = A + G(B, C, D) + x[ 1] + &H5A827999 : ROtate_Left(A, 3)
D = D + G(A, B, C) + x[ 5] + &H5A827999 : ROtate_Left(D, 5)
C = C + G(D, A, B) + x[ 9] + &H5A827999 : ROtate_Left(C, 9)
B = B + G(C, D, A) + x[13] + &H5A827999 : ROtate_Left(B, 13)
A = A + G(B, C, D) + x[ 2] + &H5A827999 : ROtate_Left(A, 3)
D = D + G(A, B, C) + x[ 6] + &H5A827999 : ROtate_Left(D, 5)
C = C + G(D, A, B) + x[10] + &H5A827999 : ROtate_Left(C, 9)
B = B + G(C, D, A) + x[14] + &H5A827999 : ROtate_Left(B, 13)
A = A + G(B, C, D) + x[ 3] + &H5A827999 : ROtate_Left(A, 3)
D = D + G(A, B, C) + x[ 7] + &H5A827999 : ROtate_Left(D, 5)
C = C + G(D, A, B) + x[11] + &H5A827999 : ROtate_Left(C, 9)
B = B + G(C, D, A) + x[15] + &H5A827999 : ROtate_Left(B, 13)

' round 3
A = A + H(B, C, D) + x[ 0] + &H6ED9EBA1 : ROtate_Left(A, 3)
D = D + H(A, B, C) + x[ 8] + &H6ED9EBA1 : ROtate_Left(D, 9)
C = C + H(D, A, B) + x[ 4] + &H6ED9EBA1 : ROtate_Left(C, 11)
B = B + H(C, D, A) + x[12] + &H6ED9EBA1 : ROtate_Left(B, 15)
A = A + H(B, C, D) + x[ 2] + &H6ED9EBA1 : ROtate_Left(A, 3)
D = D + H(A, B, C) + x[10] + &H6ED9EBA1 : ROtate_Left(D, 9)
C = C + H(D, A, B) + x[ 6] + &H6ED9EBA1 : ROtate_Left(C, 11)
B = B + H(C, D, A) + x[14] + &H6ED9EBA1 : ROtate_Left(B, 15)
A = A + H(B, C, D) + x[ 1] + &H6ED9EBA1 : ROtate_Left(A, 3)
D = D + H(A, B, C) + x[ 9] + &H6ED9EBA1 : ROtate_Left(D, 9)
C = C + H(D, A, B) + x[ 5] + &H6ED9EBA1 : ROtate_Left(C, 11)
B = B + H(C, D, A) + x[13] + &H6ED9EBA1 : ROtate_Left(B, 15)
A = A + H(B, C, D) + x[ 3] + &H6ED9EBA1 : ROtate_Left(A, 3)
D = D + H(A, B, C) + x[11] + &H6ED9EBA1 : ROtate_Left(D, 9)
C = C + H(D, A, B) + x[ 7] + &H6ED9EBA1 : ROtate_Left(C, 11)
B = B + H(C, D, A) + x[15] + &H6ED9EBA1 : ROtate_Left(B, 15)

A += AA : B += BB : C += CC : D += DD

Next

' convert A, B, C and D in hex, then add low order first
s1 = Hex(A, 8)
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
s1 = Hex(B, 8)
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
s1 = Hex(C, 8)
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
s1 = Hex(D, 8)
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next

Return LCase(answer)

End Function

' ------=< MAIN >=------

Dim As String test = "Rosetta Code"
Print
Print test; " => "; MD4(test)


' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{out}}
<pre>Rosetta Code => a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>


=={{header|C}}==
=={{header|C}}==
Line 550: Line 707:
Rosetta Code => A52BCFC6A0D0D300CDC5DDBFBEFE478B
Rosetta Code => A52BCFC6A0D0D300CDC5DDBFBEFE478B
</pre>
</pre>

=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' version 19-10-2016
' translation of the (pseudo) code in RFC 1320
' compile with: fbc -s console

Function MD4(test_str As String) As String
Dim As String message = test_str ' string are passed as ByRef

' some macro's
#Macro F(X, Y, Z)
(((X) And (Y)) Or ((Not(X)) And (Z)))
#EndMacro

#Macro G(X, Y, Z)
(((X) And (Y)) Or (((X) And (Z)) Or ((Y) And (Z))))
#EndMacro

#Macro H(X, Y, Z)
((X) Xor (Y) Xor (Z))
#EndMacro
' a little piece of inline asm to do a rotate left on a 32bit variable
#Macro ROtate_Left(x, n) ' rotate left
Asm
rol dword Ptr [x], n
End Asm
#EndMacro
' #Macro ROtate_left(x, n)
' x = x Shl n + x Shr (32 - n)
' #EndMacro
Dim As Long i
Dim As String answer, s1

Dim As ULongInt l = Len(message)
' set the first bit after the message to 1
message = message + Chr(1 Shl 7)
' add one char to the length
Dim As ULong padding = 64 - ((l +1) Mod (512 \ 8)) ' 512 \ 8 = 64 char.

' check if we have enough room for inserting the length
If padding < 8 Then padding = padding + 64

message = message + String(padding, Chr(0)) ' adjust length
Dim As ULong l1 = Len(message) ' new length

l = l * 8 ' orignal length in bits
' create ubyte ptr to point to l ( = length in bits)
Dim As UByte Ptr ub_ptr = Cast(UByte Ptr, @l)

For i = 0 To 7 'copy length of message to the last 8 bytes
message[l1 -8 + i] = ub_ptr[i]
Next

' unsigned 32bit integers only
Dim As UInteger<32> AA, A = &H67452301
Dim As UInteger<32> BB, B = &Hefcdab89
Dim As UInteger<32> CC, C = &H98badcfe
Dim As UInteger<32> DD, D = &H10325476

For i = 0 To (l1 -1) \ 64 ' split into 64 byte block

AA = A : BB = B : CC = C : DD = D

' x point to 64 byte block inside the string message
Dim As UInteger<32> Ptr x = Cast(UInteger<32> Ptr, @message[i*64])

' round 1
A = A + F(B, C, D) + x[ 0] : ROtate_Left(A, 3)
D = D + F(A, B, C) + x[ 1] : ROtate_Left(D, 7)
C = C + F(D, A, B) + x[ 2] : ROtate_Left(C, 11)
B = B + F(C, D, A) + x[ 3] : ROtate_Left(B, 19)
A = A + F(B, C, D) + x[ 4] : ROtate_Left(A, 3)
D = D + F(A, B, C) + x[ 5] : ROtate_Left(D, 7)
C = C + F(D, A, B) + x[ 6] : ROtate_Left(C, 11)
B = B + F(C, D, A) + x[ 7] : ROtate_Left(B, 19)
A = A + F(B, C, D) + x[ 8] : ROtate_Left(A, 3)
D = D + F(A, B, C) + x[ 9] : ROtate_Left(D, 7)
C = C + F(D, A, B) + x[10] : ROtate_Left(C, 11)
B = B + F(C, D, A) + x[11] : ROtate_Left(B, 19)
A = A + F(B, C, D) + x[12] : ROtate_Left(A, 3)
D = D + F(A, B, C) + x[13] : ROtate_Left(D, 7)
C = C + F(D, A, B) + x[14] : ROtate_Left(C, 11)
B = B + F(C, D, A) + x[15] : ROtate_Left(B, 19)

' round 2
A = A + G(B, C, D) + x[ 0] + &H5A827999 : ROtate_Left(A, 3)
D = D + G(A, B, C) + x[ 4] + &H5A827999 : ROtate_Left(D, 5)
C = C + G(D, A, B) + x[ 8] + &H5A827999 : ROtate_Left(C, 9)
B = B + G(C, D, A) + x[12] + &H5A827999 : ROtate_Left(B, 13)
A = A + G(B, C, D) + x[ 1] + &H5A827999 : ROtate_Left(A, 3)
D = D + G(A, B, C) + x[ 5] + &H5A827999 : ROtate_Left(D, 5)
C = C + G(D, A, B) + x[ 9] + &H5A827999 : ROtate_Left(C, 9)
B = B + G(C, D, A) + x[13] + &H5A827999 : ROtate_Left(B, 13)
A = A + G(B, C, D) + x[ 2] + &H5A827999 : ROtate_Left(A, 3)
D = D + G(A, B, C) + x[ 6] + &H5A827999 : ROtate_Left(D, 5)
C = C + G(D, A, B) + x[10] + &H5A827999 : ROtate_Left(C, 9)
B = B + G(C, D, A) + x[14] + &H5A827999 : ROtate_Left(B, 13)
A = A + G(B, C, D) + x[ 3] + &H5A827999 : ROtate_Left(A, 3)
D = D + G(A, B, C) + x[ 7] + &H5A827999 : ROtate_Left(D, 5)
C = C + G(D, A, B) + x[11] + &H5A827999 : ROtate_Left(C, 9)
B = B + G(C, D, A) + x[15] + &H5A827999 : ROtate_Left(B, 13)

' round 3
A = A + H(B, C, D) + x[ 0] + &H6ED9EBA1 : ROtate_Left(A, 3)
D = D + H(A, B, C) + x[ 8] + &H6ED9EBA1 : ROtate_Left(D, 9)
C = C + H(D, A, B) + x[ 4] + &H6ED9EBA1 : ROtate_Left(C, 11)
B = B + H(C, D, A) + x[12] + &H6ED9EBA1 : ROtate_Left(B, 15)
A = A + H(B, C, D) + x[ 2] + &H6ED9EBA1 : ROtate_Left(A, 3)
D = D + H(A, B, C) + x[10] + &H6ED9EBA1 : ROtate_Left(D, 9)
C = C + H(D, A, B) + x[ 6] + &H6ED9EBA1 : ROtate_Left(C, 11)
B = B + H(C, D, A) + x[14] + &H6ED9EBA1 : ROtate_Left(B, 15)
A = A + H(B, C, D) + x[ 1] + &H6ED9EBA1 : ROtate_Left(A, 3)
D = D + H(A, B, C) + x[ 9] + &H6ED9EBA1 : ROtate_Left(D, 9)
C = C + H(D, A, B) + x[ 5] + &H6ED9EBA1 : ROtate_Left(C, 11)
B = B + H(C, D, A) + x[13] + &H6ED9EBA1 : ROtate_Left(B, 15)
A = A + H(B, C, D) + x[ 3] + &H6ED9EBA1 : ROtate_Left(A, 3)
D = D + H(A, B, C) + x[11] + &H6ED9EBA1 : ROtate_Left(D, 9)
C = C + H(D, A, B) + x[ 7] + &H6ED9EBA1 : ROtate_Left(C, 11)
B = B + H(C, D, A) + x[15] + &H6ED9EBA1 : ROtate_Left(B, 15)

A += AA : B += BB : C += CC : D += DD

Next

' convert A, B, C and D in hex, then add low order first
s1 = Hex(A, 8)
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
s1 = Hex(B, 8)
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
s1 = Hex(C, 8)
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next
s1 = Hex(D, 8)
For i = 7 To 1 Step -2 : answer +=Mid(s1, i, 2) : Next

Return LCase(answer)

End Function

' ------=< MAIN >=------

Dim As String test = "Rosetta Code"
Print
Print test; " => "; MD4(test)


' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{out}}
<pre>Rosetta Code => a52bcfc6a0d0d300cdc5ddbfbefe478b</pre>


=={{header|Go}}==
=={{header|Go}}==