¿Cómo generar una sum de comprobación MD5 para un archivo en Android?

En mi aplicación, tengo un requisito para generar una sum de comprobación MD5 para un archivo. ¿Podría decirme si hay alguna manera de lograr esto?

Gracias.

Convierta el contenido del archivo en cadena y use el siguiente método:

public static String getMD5EncryptedString(String encTarget){ MessageDigest mdEnc = null; try { mdEnc = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { System.out.println("Exception while encrypting to md5"); e.printStackTrace(); } // Encryption algorithm mdEnc.update(encTarget.getBytes(), 0, encTarget.length()); String md5 = new BigInteger(1, mdEnc.digest()).toString(16); while ( md5.length() < 32 ) { md5 = "0"+md5; } return md5; } 

Tenga en cuenta que este enfoque simple es adecuado para cadenas pequeñas, pero no será eficiente para archivos grandes. Para este último, vea la respuesta de dentex .

Este código es de CMupdater, del CyanogenMod 10.2 android ROM. Prueba las ROM descargadas en la aplicación de actualización.

código: https://github.com/CyanogenMod/android_packages_apps_CMUpdater/blob/cm-10.2/src/com/cyanogenmod/updater/utils/MD5.java

Funciona a las mil maravillas:

 /* * Copyright (C) 2012 The CyanogenMod Project * * * Licensed under the GNU GPLv2 license * * The text of the license can be found in the LICENSE file * or at https://www.gnu.org/licenses/gpl-2.0.txt */ package com.cyanogenmod.updater.utils; import android.text.TextUtils; import android.util.Log; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class MD5 { private static final String TAG = "MD5"; public static boolean checkMD5(String md5, File updateFile) { if (TextUtils.isEmpty(md5) || updateFile == null) { Log.e(TAG, "MD5 string empty or updateFile null"); return false; } String calculatedDigest = calculateMD5(updateFile); if (calculatedDigest == null) { Log.e(TAG, "calculatedDigest null"); return false; } Log.v(TAG, "Calculated digest: " + calculatedDigest); Log.v(TAG, "Provided digest: " + md5); return calculatedDigest.equalsIgnoreCase(md5); } public static String calculateMD5(File updateFile) { MessageDigest digest; try { digest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { Log.e(TAG, "Exception while getting digest", e); return null; } InputStream is; try { is = new FileInputStream(updateFile); } catch (FileNotFoundException e) { Log.e(TAG, "Exception while getting FileInputStream", e); return null; } byte[] buffer = new byte[8192]; int read; try { while ((read = is.read(buffer)) > 0) { digest.update(buffer, 0, read); } byte[] md5sum = digest.digest(); BigInteger bigInt = new BigInteger(1, md5sum); String output = bigInt.toString(16); // Fill to 32 chars output = String.format("%32s", output).replace(' ', '0'); return output; } catch (IOException e) { throw new RuntimeException("Unable to process file for MD5", e); } finally { try { is.close(); } catch (IOException e) { Log.e(TAG, "Exception on closing MD5 input stream", e); } } } } 

Tuve la misma tarea y este código funciona excelente:

 public static String fileToMD5(String filePath) { InputStream inputStream = null; try { inputStream = new FileInputStream(filePath); byte[] buffer = new byte[1024]; MessageDigest digest = MessageDigest.getInstance("MD5"); int numRead = 0; while (numRead != -1) { numRead = inputStream.read(buffer); if (numRead > 0) digest.update(buffer, 0, numRead); } byte [] md5Bytes = digest.digest(); return convertHashToString(md5Bytes); } catch (Exception e) { return null; } finally { if (inputStream != null) { try { inputStream.close(); } catch (Exception e) { } } } } private static String convertHashToString(byte[] md5Bytes) { String returnVal = ""; for (int i = 0; i < md5Bytes.length; i++) { returnVal += Integer.toString(( md5Bytes[i] & 0xff ) + 0x100, 16).substring(1); } return returnVal.toUpperCase(); } 
 public static String getMd5OfFile(String filePath) { String returnVal = ""; try { InputStream input = new FileInputStream(filePath); byte[] buffer = new byte[1024]; MessageDigest md5Hash = MessageDigest.getInstance("MD5"); int numRead = 0; while (numRead != -1) { numRead = input.read(buffer); if (numRead > 0) { md5Hash.update(buffer, 0, numRead); } } input.close(); byte [] md5Bytes = md5Hash.digest(); for (int i=0; i < md5Bytes.length; i++) { returnVal += Integer.toString( ( md5Bytes[i] & 0xff ) + 0x100, 16).substring( 1 ); } } catch(Throwable t) {t.printStackTrace();} return returnVal.toUpperCase(); } 

amigo intente seguir el código

 MessageDigest md = MessageDigest.getInstance("MD5"); InputStream is = new FileInputStream("file.txt"); try { is = new DigestInputStream(is, md); // read stream to EOF as normal... } finally { is.close(); } byte[] digest = md.digest(); 

Este método funcionó para mí, en un archivo comprimido de 131MB. MD5 calculó las coincidencias calculadas en el mismo archivo por AccuHash ( http://www.accuhash.com )

 public static String calculateMD5(File updateFile) { MessageDigest digest; try { digest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { Log.e("calculateMD5", "Exception while getting Digest", e); return null; } InputStream is; try { is = new FileInputStream(updateFile); } catch (FileNotFoundException e) { Log.e("calculateMD5", "Exception while getting FileInputStream", e); return null; } byte[] buffer = new byte[8192]; int read; try { while ((read = is.read(buffer)) > 0) { digest.update(buffer, 0, read); } byte[] md5sum = digest.digest(); BigInteger bigInt = new BigInteger(1, md5sum); String output = bigInt.toString(16); // Fill to 32 chars output = String.format("%32s", output).replace(' ', '0'); return output; } catch (IOException e) { throw new RuntimeException("Unable to process file for MD5", e); } finally { try { is.close(); } catch (IOException e) { Log.e("calculateMD5", "Exception on closing MD5 input stream", e); } } } 

He encontrado lo siguiente para trabajar realmente bien:

 Process process = Runtime.getRuntime().exec("md5 "+fileLocation); BufferedReader inputStream = new BufferedReader(new InputStreamReader(process.getInputStream())); String result = inputStream.readLine().split(" ")[0]; 

Esto llama al comando incorporado md5 . La variable fileLocation debe establecerse en la ubicación del archivo. Por supuesto, recomiendo construir algunos controles aquí para verificar que el archivo exista.

Si necesita calcular MD5 del archivo grande , puede usar esto:

Importar:

 import java.security.MessageDigest; 

Método:

  private byte[] calculateMD5ofFile(String location) throws IOException, NoSuchAlgorithmException { FileInputStream fs= new FileInputStream(location); MessageDigest md = MessageDigest.getInstance("MD5"); byte[] buffer=new byte[bufferSize]; int bytes=0; do{ bytes=fs.read(buffer,0,bufferSize); if(bytes>0) md.update(buffer,0,bytes); }while(bytes>0); byte[] Md5Sum = md.digest(); return Md5Sum; } 

Refrence: https://docs.oracle.com/javase/7/docs/api/java/security/MessageDigest.html


Para convertir la matriz de bytes a Hex. utilizar esta

 public static String ByteArraytoHexString(byte[] bytes) { StringBuilder hexString = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(bytes[i] & 0xFF); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } 

Refrence En Java, ¿cómo convierto una matriz de bytes a una cadena de dígitos hexadecimales mientras mantengo los ceros a la izquierda?