2010-05-13 16 views
6

Comment puis-je obtenir le hachage hexadécimal MD5 pour un fichier en utilisant VBA?Comment obtenir le hachage MD5 hexadécimal pour un fichier en utilisant VBA?

J'ai besoin d'une version qui fonctionne pour un fichier.

Quelque chose d'aussi simple que ce code Python:

import hashlib 

def md5_for_file(fileLocation, block_size=2**20): 
    f = open(fileLocation) 
    md5 = hashlib.md5() 
    while True: 
     data = f.read(block_size) 
     if not data: 
      break 
     md5.update(data) 
    f.close() 
    return md5.hexdigest() 

Mais en VBA.

Répondre

3
+0

Cela ne fait que le hachage d'une chaîne. Si un fichier a 700mb, je ne peux pas tout mettre dans une chaîne et faire le hachage md5 dessus. Alors, y a-t-il un hash md5 pour la version des fichiers ou une autre solution? : P –

-1

Cela devrait le faire:

 Dim fileBytes() As Byte = File.ReadAllBytes(path:=fullPath) 
     Dim Md5 As New MD5CryptoServiceProvider() 
     Dim byteHash() As Byte = Md5.ComputeHash(fileBytes) 
     Return Convert.ToBase64String(byteHash) 
+0

Huh? Tout d'abord, c'est VB.NET et non VBA et en second lieu, vous omettez certaines commandes d'importation très importantes. – Ben

+0

Oups, j'avais mal lu VBA comme VB.NET. VBA serait un peu plus difficile, car il ne dispose pas de tout le support .NET framework qui rend le code ci-dessus si simple. En ce qui concerne les importations, Visual Studio vous suggérera probablement celles-ci automatiquement, mais pour des raisons de complétude, elles sont System.IO et System.Security.Cryptography. –

14

Une question plus qui pourrait utiliser une meilleure réponse. Ces fonctions sont spécifiques pour le hachage de fichiers, pas pour le hachage de mots de passe. En prime, j'inclus une fonction pour SHA1. Si vous supprimez les déclarations de type, ces fonctions fonctionnent également dans VBScript, sauf que la fonction GetFileBytes doit être modifiée pour utiliser FileSystemObject (ou éventuellement ADO Stream) car le fichier libre n'existe pas dans VBScript.

Private Sub TestMD5() 
    Debug.Print FileToMD5Hex("C:\test.txt") 
    Debug.Print FileToSHA1Hex("C:\test.txt") 
End Sub 

Public Function FileToMD5Hex(sFileName As String) As String 
    Dim enc 
    Dim bytes 
    Dim outstr As String 
    Dim pos As Integer 
    Set enc = CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider") 
    'Convert the string to a byte array and hash it 
    bytes = GetFileBytes(sFileName) 
    bytes = enc.ComputeHash_2((bytes)) 
    'Convert the byte array to a hex string 
    For pos = 1 To LenB(bytes) 
     outstr = outstr & LCase(Right("0" & Hex(AscB(MidB(bytes, pos, 1))), 2)) 
    Next 
    FileToMD5Hex = outstr 
    Set enc = Nothing 
End Function 

Public Function FileToSHA1Hex(sFileName As String) As String 
    Dim enc 
    Dim bytes 
    Dim outstr As String 
    Dim pos As Integer 
    Set enc = CreateObject("System.Security.Cryptography.SHA1CryptoServiceProvider") 
    'Convert the string to a byte array and hash it 
    bytes = GetFileBytes(sFileName) 
    bytes = enc.ComputeHash_2((bytes)) 
    'Convert the byte array to a hex string 
    For pos = 1 To LenB(bytes) 
     outstr = outstr & LCase(Right("0" & Hex(AscB(MidB(bytes, pos, 1))), 2)) 
    Next 
    FileToSHA1Hex = outstr 'Returns a 40 byte/character hex string 
    Set enc = Nothing 
End Function 

Private Function GetFileBytes(ByVal path As String) As Byte() 
    Dim lngFileNum As Long 
    Dim bytRtnVal() As Byte 
    lngFileNum = FreeFile 
    If LenB(Dir(path)) Then ''// Does file exist? 
     Open path For Binary Access Read As lngFileNum 
     ReDim bytRtnVal(LOF(lngFileNum) - 1&) As Byte 
     Get lngFileNum, , bytRtnVal 
     Close lngFileNum 
    Else 
     Err.Raise 53 
    End If 
    GetFileBytes = bytRtnVal 
    Erase bytRtnVal 
End Function 
+0

Question rapide: La variable "asc" de UTF8Encoding n'est utilisée nulle part, est-ce que cela sert un but? Aussi, pour qu'il fonctionne avec VBScript, vous devrez probablement ouvrir le fichier en utilisant un objet ADODB.Stream au lieu de la méthode FreeFile ... En tout cas Great share! –

+0

Je pense que le truc «asc» doit avoir été des artefacts de quand j'ai utilisé ce code pour hacher les mots de passe. Je l'ai enlevé maintenant. Et oui, Free File n'existe pas dans VBScript. J'ai trouvé une fonction que je pense qui pourrait être faite pour travailler qui utilise l'objet système de fichiers: http://stackoverflow.com/questions/6060529/read-and-write-binary-file-in-vbscript – HK1

+0

Bonne solution, avec un couple de lentes à choisir ... 'Dim bytes() Comme Byte' offre un petit gain; et le passer par référence dans un Private Sub GetFileBytes reconfiguré (sFileName As String, arrBytes() As Byte) signifie que vous évitez une allocation de mémoire redondante - et c'est un gain * réel *, pour l'utilisation des ressources et les performances. L'éléphant dans la pièce est que, pour des fichiers vraiment volumineux, 'ReDim bytRtnVal (LOF (lngFileNum) - 1 &) As Byte' provoquera des erreurs. Mais je ne peux rien publier de mieux, parce que je ne connais pas d'API de «segmentation» ou de streaming dans les fonctions System.Security.Cryptography. –