在Python中生成图片的md5值,并在Android应用中验证
几天前,我在这里问了一个问题,关于如何从一个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都能以相同的方式解压原始文件(这看起来是很有可能的)。