首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >仅计算镜像的核心镜像数据(不包括元数据)的哈希值

仅计算镜像的核心镜像数据(不包括元数据)的哈希值
EN

Stack Overflow用户
提问于 2012-04-09 22:53:33
回答 4查看 7.9K关注 0票数 24

我正在编写一个脚本来计算不包括EXIF标记的图像的MD5和。

为了准确地做到这一点,我需要知道EXIF标记在文件中的位置(开始、中间、结束),以便我可以排除它。

如何确定标记在文件中的位置?

我正在扫描的图像格式是TIFF、JPG、PNG、BMP、DNG、CR2、NEF,以及一些视频MOV、AVI和MPG。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-04-09 23:01:49

一种简单的方法是对核心图像数据进行散列。对于PNG,您可以通过只计算“关键块”(即以大写字母开头的块)来实现这一点。JPEG具有类似但更简单的文件结构。

ImageMagick中的可视散列在对图像进行散列时对其进行解压缩。在您的情况下,您可以立即散列压缩的图像数据,因此(如果实现正确)它应该和散列原始文件一样快。

这是一个很小的Python脚本,用来说明这个想法。它可能对您起作用,也可能不起作用,但至少应该给出我的意思的一个指示:)

代码语言:javascript
复制
import struct
import os
import hashlib

def png(fh):
    hash = hashlib.md5()
    assert fh.read(8)[1:4] == "PNG"
    while True:
        try:
            length, = struct.unpack(">i",fh.read(4))
        except struct.error:
            break
        if fh.read(4) == "IDAT":
            hash.update(fh.read(length))
            fh.read(4) # CRC
        else:
            fh.seek(length+4,os.SEEK_CUR)
    print "Hash: %r" % hash.digest()

def jpeg(fh):
    hash = hashlib.md5()
    assert fh.read(2) == "\xff\xd8"
    while True:
        marker,length = struct.unpack(">2H", fh.read(4))
        assert marker & 0xff00 == 0xff00
        if marker == 0xFFDA: # Start of stream
            hash.update(fh.read())
            break
        else:
            fh.seek(length-2, os.SEEK_CUR)
    print "Hash: %r" % hash.digest()


if __name__ == '__main__':
    png(file("sample.png"))
    jpeg(file("sample.jpg"))
票数 8
EN

Stack Overflow用户

发布于 2012-08-29 18:33:57

使用Python Imaging来提取图片数据(iPython中的示例)要容易得多:

代码语言:javascript
复制
In [1]: import Image

In [2]: import hashlib

In [3]: im = Image.open('foo.jpg')

In [4]: hashlib.md5(im.tobytes()).hexdigest()
Out[4]: '171e2774b2549bbe0e18ed6dcafd04d5'

这适用于PIL可以处理的任何类型的图像。tobytes方法返回包含像素数据的字符串。

顺便说一下,MD5散列现在被认为是相当弱的。最好使用SHA512:

代码语言:javascript
复制
In [6]: hashlib.sha512(im.tobytes()).hexdigest()
Out[6]: '6361f4a2722f221b277f81af508c9c1d0385d293a12958e2c56a57edf03da16f4e5b715582feef3db31200db67146a4b52ec3a8c445decfc2759975a98969c34'

在我的机器上,计算2500x1600JPEG的MD5校验和大约需要0.07秒。使用SHA512,它需要0,10秒。完整示例:

代码语言:javascript
复制
#!/usr/bin/env python3

from PIL import Image
import hashlib
import sys

im = Image.open(sys.argv[1])
print(hashlib.sha512(im.tobytes()).hexdigest(), end="")

对于电影,您可以使用例如ffmpeg从其中提取帧,然后按照上面所示的方式处理它们。

票数 22
EN

Stack Overflow用户

发布于 2018-02-23 18:44:40

您可以使用ImageMagick套件中的stream

代码语言:javascript
复制
$ stream -map rgb -storage-type short image.tif - | sha256sum
d39463df1060efd4b5a755b09231dcbc3060e9b10c5ba5760c7dbcd441ddcd64  -

代码语言:javascript
复制
$ sha256sum <(stream -map rgb -storage-type short image.tif -)
d39463df1060efd4b5a755b09231dcbc3060e9b10c5ba5760c7dbcd441ddcd64  /dev/fd/63

此示例适用于RGB格式的TIFF文件,每个样本具有16位(即每像素48位)。所以我使用map to rgb和一个short storage-type (如果RGB值是8位,你可以在这里使用char )。

此方法报告与verbose Imagemagick identify命令报告的相同signature哈希:

代码语言:javascript
复制
$ identify -verbose image.tif | grep signature
signature: d39463df1060efd4b5a755b09231dcbc3060e9b10c5ba5760c7dbcd441ddcd64

(对于ImageMagick v6.x;identify在版本7上报告的散列与使用stream获得的散列是different的,但后者可以由任何能够提取原始位图数据的工具重现-例如对于某些图像类型的dcraw。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10075065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档