从UIImage生成哈希

Ree*_*sen 20 iphone hash cocoa-touch

我试图比较文件系统中的两个UIImages,看看它们是否相同.显然,我不能使用NSObject的哈希方法,因为这会返回对象的哈希值,而不是实际的图像数据.

我发现代码从字符串生成MD5哈希,但我还没有发现如何为UIImage实现它.

我应该怎样去散列UIImage呢?或者我的方法是完全关闭图像?

Ree*_*sen 36

我使用以下代码完成任务.请注意,这需要您导入<CommonCrypto/CommonDigest.h>:

unsigned char result[CC_MD5_DIGEST_LENGTH];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(inImage)];
CC_MD5([imageData bytes], [imageData length], result);
NSString *imageHash = [NSString stringWithFormat:
                       @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
                       result[0], result[1], result[2], result[3], 
                       result[4], result[5], result[6], result[7],
                       result[8], result[9], result[10], result[11],
                       result[12], result[13], result[14], result[15]
                       ];
Run Code Online (Sandbox Code Playgroud)

  • 也许是一个愚蠢的问题,但这需要在App Store提交中"我添加加密"检查吗? (4认同)
  • 如果值发生变化,您应该使用`CC_MD5_DIGEST_LENGTH`而不是`16`. (2认同)

cod*_*gic 9

一个不太理想的解决方案:

[ UIImagePNGRepresentation( uiImage1 ) isEqualToData: 
      UIImagePNGRepresentation( uiImage2 ) ];
Run Code Online (Sandbox Code Playgroud)

这基本上比较了2个图像的PNG编码数据.由于图像相似性是一个复杂的主题,因此可以根据最终目标的确切设计出更好更快的解决方案(即,您希望比较图像,逐个像素,还是只是近似相似性,这可能会使用源的下采样版本图像等).


And*_*eas 5

UIImage哈希

Swift代码,用于在swift 4.2中使用SHA256算法对UIImage进行哈希处理。您还可以使用其他算法,这些算法可能更快或产生更少的重复,但是对于大多数用例而言,这一算法已经足够了。

只需将代码放在项目中的某个位置,然后像这样使用它: yourUIImage.sha256()

extension UIImage{

    public func sha256() -> String{
        if let imageData = cgImage?.dataProvider?.data as? Data {
            return hexStringFromData(input: digest(input: imageData as NSData))
        }
        return ""
    }

    private func digest(input : NSData) -> NSData {
        let digestLength = Int(CC_SHA256_DIGEST_LENGTH)
        var hash = [UInt8](repeating: 0, count: digestLength)
        CC_SHA256(input.bytes, UInt32(input.length), &hash)
        return NSData(bytes: hash, length: digestLength)
    }

    private  func hexStringFromData(input: NSData) -> String {
        var bytes = [UInt8](repeating: 0, count: input.length)
        input.getBytes(&bytes, length: input.length)

        var hexString = ""
        for byte in bytes {
            hexString += String(format:"%02x", UInt8(byte))
        }

        return hexString
    }
}
Run Code Online (Sandbox Code Playgroud)

桥接头

顺便说一句,您需要一个导入CommonCrypto的桥接头。如果您没有,请按照以下步骤操作:

  1. 创建新文件->头文件->另存为 BridgingHeader
  2. 在构建设置-> Objective-C桥接标题->添加中 ProjectName/BridgingHeader.h
  3. 放入#import <CommonCrypto/CommonHMAC.h>您的头文件

重复概率

重复的可能性很低,但是如果您拥有大量数据集,则可以相对容易地升级到SHA512:

重复概率大约是:

在此处输入图片说明

资料来源:https : //crypto.stackexchange.com/questions/24732/probability-of-sha256-collisions-for-certain-amount-of-hashed-values