' Requires VB Editor Reference mscorlib.dll
Sub SHA512()
Dim toHash As String: toHash = "Hello World"
Dim salt As String: salt = "!"
Debug.Print GetSHA512Hash(toHash & salt)
End Sub
Function GetSHA512Hash(toHash As String) As String
' Ref: https://stackoverflow.com/questions/11394811/compute-sha512-on-vba-excel-2003
Dim text As Object: Set text = CreateObject("System.Text.UTF8Encoding")
Dim SHA512 As Object: Set SHA512 = CreateObject("System.Security.Cryptography.SHA512Managed")
GetSHA512Hash = ToBase64String(SHA512.ComputeHash_2((text.GetBytes_4(toHash))))
End Function
Function ToBase64String(rabyt)
' Ref: http://stackoverflow.com/questions/1118947/converting-binary-file-to-base64-string
With CreateObject("MSXML2.DOMDocument")
.LoadXML "<root />"
.DocumentElement.DataType = "bin.base64"
.DocumentElement.nodeTypedValue = rabyt
ToBase64String = Replace(.DocumentElement.text, vbLf, "")
End With
End Function
Having revisited this and looking into it in a bit more depth, the SHA-512 implementation is a bit more convoluted than I had previously realised. There is the repeated hashing of the salted result which I had missed and the functionality I coded used Base64 whereas the Java implementation is hexadecimal, so an incorrect string was continually being passed into the code, so no wonder it was out.
Updated code below which gives the same result as the Java code when trialled here
Sub SHA512()
Dim toHash As String: toHash = "123"
Dim Salt As String: Salt = "AAZZ"
Debug.Print toHash, GetSHA512Hash(toHash, Salt, 100000)
End Sub
Function GetSHA512Hash(ByVal toHash As String, Optional ByVal Salt As String, Optional Rounds As Long) As String
If Rounds = 0 Then Rounds = 100
If Rounds > 0 Then
Dim i As Long: For i = 1 To Rounds
toHash = SHA512Round(toHash + Salt)
Next i
End If
GetSHA512Hash = SHA512Round(toHash)
End Function
Function SHA512Round(toHash As String) As String
' Ref: https://stackoverflow.com/questions/11394811/compute-sha512-on-vba-excel-2003
Dim text As Object: Set text = CreateObject("System.Text.UTF8Encoding")
Dim SHA512 As Object: Set SHA512 = CreateObject("System.Security.Cryptography.SHA512Managed")
SHA512Round = EncodeHex(SHA512.ComputeHash_2(text.GetBytes_4(toHash)))
End Function
Function EncodeHex(ByVal strBytes) As String
Dim xmlNode16 As Object: Set xmlNode16 = CreateObject("MSXML2.DOMDocument").createElement("objNode")
xmlNode16.DataType = "bin.hex"
xmlNode16.nodeTypedValue = strBytes
EncodeHex = xmlNode16.text
Set xmlNode16 = Nothing
End Function
Setting Rounds
as negative allows you to skip the salted string and gives the same kind of result as the GeeksforGeeks Site Test
I have also made the number of rounds optional as using 100,000 takes a bit more time in VBA than it does in Java.