我想使用哈希来唯一识别来自Android手机的照片,以回答does server have xyz?
和fetch image which hashes to xyz
的查询。我面对这个:
我必须从图像文件中散列多少个字符,这样才能让发生事故的几率降低?是否有更好的索引方案?
答案 0 :(得分:2)
只要您将任何字节留在哈希值之外,您就有机会创建(有意或无意地)仅在这些字节上不同的文件,因此哈希值相同。
这个图像与原始图像的实际外观有多大程度上取决于您在哈希中留出多少字节,以及在哪里。但是你首先必须决定你可以容忍哪些哈希冲突(故意/偶然和主要/次要),然后你可以考虑你可以使用多快的哈希函数,以及你需要包含多少数据。
除非您愿意容忍数据更改的“大块”,否则您需要在哈希中包含每个“大块”的字节。从I / O性能的角度来看,这意味着您需要访问几乎所有文件,因为读取甚至一个字节将导致硬件读取包含它的整个块。
可能要做的事情是从“绝对足够好”开始,例如整个文件的SHA-256哈希。看看有多慢,然后考虑如何以所需的百分比提高性能。例如,如果它只有50%太慢,你可以用更快(不太安全)的哈希来解决问题,但仍然包括所有数据。
通过实现一些完全无关紧要的哈希(例如文件中所有4字节字的XOR),您可以计算出安全性较低的哈希速度限制,并查看运行速度有多快。如果这仍然太慢,那么你需要放弃文件的准确性和散列部分(假设你已经尽力优化I / O)。
如果您愿意容忍碰撞,那么对于大多数(全部?)图像格式,仅在标题中有足够的信息来唯一地标识“正常”照片。这不会保护您免受故意碰撞或图像处理结果的影响,但除了恶意之外,时间戳,图像大小,相机型号等,以及甚至少量的图像数据在实践中都将唯一地识别“某人服用的每个实例”一张照片“。所以在这个基础上,你可以只散列文件的第一个64-128k(或者更少,我很慷慨地包括EXIF标题的最大大小加上一些)并且有一个哈希适用于大多数实际目的但是可以如果有人想要被殴打。
Btw,除非是由一位认真负责的摄影师故意做的(或者除非为了实现这一目的而故意对图像进行后期处理),否则在右下角拍摄相同场景的两张照片将会不< / em>在图像数据的开头产生相同的字节。如果您处于无法控制光线的环境中,甚至不能靠近。试试看吧。当使用为图像添加时间戳的典型相机完成时,它肯定不会产生相同的文件。所以,如果你只是想要防范意外事故,那么问题要容易得多,而不是你想要防范欺骗。答案 1 :(得分:0)
我认为最有效的方法是选择随机字节(先前选择,并且整个静态)并计算XOR或其他一些简单的哈希应该足够好。