在Python中生成图片的md5值,并在Android应用中验证

3 投票
1 回答
666 浏览
提问于 2025-04-17 17:54

几天前,我在这里问了一个问题,关于如何从一个android.graphics.Bitmap对象生成md5值。用户Leonidos给了我很大的帮助,他推荐的方法确实有效。但是,我之前用同样的图片生成的md5值却不一样。

我使用的Android代码如下:

public String md5ForBitmap(Bitmap bitmap)
{
    String hash = "";
    try
    {
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        byte[] bitmapBytes = stream.toByteArray();

        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(bitmapBytes);
        byte[] digestedBytes = messageDigest.digest();

        BigInteger intRep = new BigInteger(1, digestedBytes);
        hash = intRep.toString(16);
    }
    catch (NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    return hash;
}

而Python脚本看起来是这样的:

def begin(path):
    os.chdir(path)
    files = glob.glob("*")

    for file in files:
        processFile(file, path)

def processFile(file, folder):
    with open(file, "r") as picture:
        fileContents = picture.read()
        md5 = hashlib.md5()
        md5.update(fileContents)
        hash = md5.hexdigest()
        print file + "   :   " + hash

这个Android应用从服务器接收到一个json字符串,里面包含了图片的URL和md5值。这个md5值是之前用Python脚本计算出来的。在下载完图片后,我得到了一个Bitmap对象,然后在应用中使用它。

Leonidos建议说,Bitmap对象的处理方式和Python处理图片数据的方式不一样,所以我需要在Android中找到原始图片数据的md5值。对我来说,这听起来是个很合理的解释。只是我对这一切真的感到很迷茫。

那么,正确的做法是什么呢?

1 个回答

1

这只是个有根据的猜测,但我觉得很明显,如果你想要和未压缩的文件得到相同的MD5哈希值,就不应该用JPEG格式来压缩位图。

你可以尝试使用copyPixelsToBuffer这个方法,然后把你的Python代码调整一下,只读取实际的像素数据,忽略掉头部信息等等。用PIL库来做这件事其实很简单。

位图类内部其实就是一个未压缩的像素缓冲区,所以你甚至无法从中获取原始文件的内容。只用实际的像素值来计算哈希值可以完全避免这个问题,只要位图类和PIL都能以相同的方式解压原始文件(这看起来是很有可能的)。

撰写回答