2010-05-13 79 views
6

¿Cómo puedo obtener el hash hexadecimal MD5 para un archivo usando VBA?¿Cómo obtener el hash hexadecimal MD5 para un archivo usando VBA?

Necesito una versión que funcione para un archivo.

Algo tan simple como el código 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() 

Pero en VBA.

Respuesta

3
+0

Eso solo hace el hash de una cuerda. Si un archivo tiene 700mb, no puedo ponerlo todo en una cadena y hacer el hash md5 en él. Entonces, ¿hay un hash md5 para la versión de archivos u otra solución? : P –

-1

Esto debe hacerlo:

 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

¿Eh? Primero, eso es VB.NET no VBA y segundo, estás omitiendo algunos comandos Importantes muy importantes. – Ben

+0

Vaya, he leído mal VBA como VB.NET. VBA sería un poco más difícil, ya que no tiene todo el soporte de .NET framework que hace que el código anterior sea tan simple. En cuanto a las importaciones, Visual Studio probablemente lo sugerirá automáticamente, pero para completarlas, son System.IO y System.Security.Cryptography. –

14

Una cuestión edad que puedan utilizar una mejor respuesta. Estas funciones son específicamente para hash de archivos, no para contraseñas hash. Como beneficio adicional, incluyo una función para SHA1. Si se deshace de las declaraciones de tipo, estas funciones también funcionan en VBScript, excepto que la función GetFileBytes debe cambiarse para usar FileSystemObject (o posiblemente ADO Stream) ya que Free File no existe en 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

Pregunta rápida: La variable "asc" para el UTF8Encoding no se usa en ningún lado, ¿sirve esto para un propósito? Además, para que funcione con VBScript, probablemente debas abrir el archivo utilizando un objeto ADODB.Stream en lugar del método FreeFile ... En cualquier caso, Great share! –

+0

Creo que las cosas "asc" deben haber sido artefactos de cuando estaba usando este código para hash passwords. Lo he eliminado ahora. Y sí, Free File no existe en VBScript. Encontré una función que creo que podría funcionar para usar el objeto del sistema de archivos: http://stackoverflow.com/questions/6060529/read-and-write-binary-file-in-vbscript – HK1

+0

Buena solución, con un par de liendres para elegir ... 'Dim bytes() As Byte' ofrece una pequeña ganancia; y pasarlo por referencia a un 'Sub GetFileBytes privado (sFileName como cadena, arrBytes() como byte)' reconfigurado significa que eludirá una asignación de memoria redundante, y esa es una ganancia * real * para el uso y el rendimiento de los recursos. El elefante en la sala es que, para archivos realmente grandes, 'ReDim bytRtnVal (LOF (lngFileNum) - 1 &) As Byte' provocará errores. Pero no puedo publicar nada mejor, porque no conozco ninguna API de "fragmentación" o transmisión en las funciones de System.Security.Cryptography. –

Cuestiones relacionadas