it-swarm.com.de

Wie generiere ich eine MD5-Prüfsumme für eine Datei in Android?

In meiner App muss ich eine MD5-Prüfsumme für eine Datei erstellen. Könnten Sie mir bitte sagen, ob es einen Weg gibt, auf dem dies möglich ist?

Vielen Dank.

57
Ingrid Cooper

Konvertieren Sie den Dateiinhalt in einen String und verwenden Sie die untenstehende Methode:

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;
    }

Beachten Sie, dass dieser einfache Ansatz für kleinere Zeichenfolgen geeignet ist, für große Dateien jedoch nicht effizient ist. Für letzteres siehe die Antwort von dentex .

38
hemu

Dieser Code stammt aus dem CMupdater, aus dem CyanogenMod 10.2 Android ROM ..__ und testet die heruntergeladenen ROMs in die Updater-App.

code: https://github.com/CyanogenMod/Android_packages_apps_CMUpdater/blob/cm-10.2/src/com/cyanogenmod/updater/utils/MD5.Java

Es wirkt wie ein Zauber:

/*
 * 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);
            }
        }
    }
}
123
dentex

Ich hatte die gleiche Aufgabe und dieser Code funktioniert ausgezeichnet:

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();
}
7
yuralife
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();
}
4
XXX

kumpel versuchen Sie folgenden Code

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();
2
Ronak Mehta

Diese Methode funktionierte für mich mit einer 131MB-Zip-Datei. MD5 berechnete Übereinstimmungen, die in derselben Datei von AccuHash ( http://www.accuhash.com ) berechnet wurden

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);
            }
        }
    }   
2
gman413

Ich habe folgendes gefunden, um wirklich gut zu funktionieren:

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

Dies ruft den integrierten md5-Befehl auf. Die Variable fileLocation soll auf den Ort der Datei gesetzt werden. Natürlich empfehle ich, hier einige Überprüfungen zu erstellen, um zu überprüfen, ob die Datei vorhanden ist.

Wenn Sie MD5 der großen Datei berechnen benötigen, können Sie Folgendes verwenden:

Einführen:

import Java.security.MessageDigest;

Methode:

 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;
    }

Aktualisierung: https://docs.Oracle.com/javase/7/docs/api/Java/security/MessageDigest.html


Zum Konvertieren eines Byte-Arrays in Hex. benutze das

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();
}

Aktualisieren Wie konvertiere ich in Java ein Byte-Array in eine Folge von Hex-Ziffern, wobei führende Nullen beibehalten werden?

0
Mahdi Rafatjah