Question

This code will compute the hash of a URI:

protected void ShowHash(android.net.Uri uri) {
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("MD5");
        BufferedInputStream is = new BufferedInputStream(getContentResolver().openInputStream(uri));
        DigestInputStream dis = new DigestInputStream(is, md);
        while(dis.read() != -1) ;
        Toast.makeText(getApplicationContext(), bytesToHex(md.digest()),
                Toast.LENGTH_LONG).show();
    } catch(Exception e) {
        Toast.makeText(getApplicationContext(), e.toString(),
                Toast.LENGTH_LONG).show();
    }
    return;
}

But for a decent sized file (say, a 2MB picture), this will hang for about 10 seconds, which is a ridiculous amount of time. There is obviously a better way to process the whole file than while(dis.read() != -1) ;; how should I go about it?

Was it helpful?

Solution

A better way is to read the file in larger chunks. This avoids the overhead of many function calls for each byte. Of course, you don't want to read the entire file into memory, so you can just use a small buffer:

protected void ShowHash(android.net.Uri uri) {
    MessageDigest md = null;
    try {
        md = MessageDigest.getInstance("MD5");
        BufferedInputStream is = new BufferedInputStream(getContentResolver().openInputStream(uri));
        DigestInputStream dis = new DigestInputStream(is, md);
        byte[] buffer = new byte[1024];
        while(dis.read(buffer, 0, buffer.length) != -1) ;
        Toast.makeText(getApplicationContext(), bytesToHex(md.digest()),
                Toast.LENGTH_LONG).show();
    } catch(Exception e) {
        Toast.makeText(getApplicationContext(), e.toString(),
                Toast.LENGTH_LONG).show();
    }
    return;
}

This function returns instantly where the original function takes around 10 seconds.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top