【问题标题】:Swift: Calculated md5 hash of image file doesn't match with terminal and other hash generatorSwift:计算的图像文件的 md5 哈希与终端和其他哈希生成器不匹配
【发布时间】:2021-06-06 07:59:12
【问题描述】:

我想计算图像的哈希值,首先我将图像转换为数据,然后在此函数的帮助下我将计算图像文件(数据)的哈希值,但生成的哈希值与在线生成器和其他语言不匹配像(Java)这样的转换器,即使我尝试了其他库,但我得到了相同的结果,我认为当我转换为数据时,我的文件发生了一些事情,所以哈希与其他转换器不匹配。

但是当我计算纯文本哈希时,它与所有在线转换器和其他语言转换器匹配 但是和Image不一样?

终端生成的哈希值不同

感谢您的帮助

   func md5(url: URL) {
          let bufferSize = 1024*1024
          do {
            let file = try FileHandle.init(forReadingFrom: url)
              defer {
                  file.closeFile()
              }

              var context = CC_MD5_CTX.init()
              CC_MD5_Init(&context)
              while case let data = file.readData(ofLength: bufferSize), data.count > 0 {
                  data.withUnsafeBytes { (poiner) -> Void in
                      _ = CC_MD5_Update(&context, poiner, CC_LONG(data.count))
                  }
              }

                           // Calculate the MD5 summary
              var digest = Data(count: Int(CC_MD5_DIGEST_LENGTH))
              digest.withUnsafeMutableBytes { (pointer) -> Void in
                  _ = CC_MD5_Final(pointer, &context)
              }
              let result = digest.map { (byte) -> String in
                  String.init(format: "%02hhx", byte)
              }.joined()
              print("result: \(result)")
          } catch let error as Error {
              print("calculation error: \(error.localizedDescription)") // Where is the try, where is the error?
          }
      }

【问题讨论】:

  • 应该可以 - 你确定你有正确的文件吗?
  • 是的,我将 png 图像转换为数据并使用 2 个不同的库计算哈希,我会得到相同的结果,但是在线转换器和终端我会收到不同的哈希
  • 展示如何将 png 转换为数据。注意 png != data ... 有可能不同的 cmets 和其他元数据。如果 url = original png 这应该有效
  • 让 image = UIImage(named: "aaaaaaaaa")?.pngData().但我没有得到你关于 url 的内容
  • 我的意思是,在您的代码中,如果您使用 xxx 调用 md5 ( url : xxx ) 原始图像,它应该可以工作。 pngData() 将产生省略或添加元数据的数据,因此!= 其他 md5 操作的文件数据。

标签: ios objective-c swift iphone md5


【解决方案1】:

好的,这是一个小测试。为此,我将 png 和一些随机文件拖到项目中。它们在下图中突出显示。

请注意,我将文件直接添加到项目中,而不是资产中。我在 cmets 中链接的那个答案实际上提到您无法直接获取图像,但正如您所指出的,它也保存为 png 数据。

该项目是一个标准的 iOS SwiftUI 应用程序,我将以下代码添加到自动生成的 ContentView.swift 文件中。

import SwiftUI
import CommonCrypto

struct ContentView: View
{
    var body: some View
    {
        Text("Hello, world!")
            .padding()
            .onAppear
            {
                md5 ( url : Bundle.main.url(forResource: "t", withExtension: "png" ) )
                md5 ( url : Bundle.main.url(forResource: "something", withExtension: "ext" ) )
            }
    }
}

func md5 ( url : URL? ) -> Void
{
    if url == nil
    {
        print ( "Skipping empty url" )
        return
    }
    else
    {
        print ( "Summing \( url )" )
    }

    let bufferSize = 1024*1024
    do {
        let file = try FileHandle.init(forReadingFrom: url!)
        defer {
            file.closeFile()
        }
        
        var context = CC_MD5_CTX.init()
        CC_MD5_Init(&context)
        while case let data = file.readData(ofLength: bufferSize), data.count > 0 {
            data.withUnsafeBytes { (poiner) -> Void in
                _ = CC_MD5_Update(&context, poiner, CC_LONG(data.count))
            }
        }
        
        // Calculate the MD5 summary
        var digest = Data(count: Int(CC_MD5_DIGEST_LENGTH))
        digest.withUnsafeMutableBytes { (pointer) -> Void in
            _ = CC_MD5_Final(pointer, &context)
        }
        let result = digest.map { (byte) -> String in
            String.init(format: "%02hhx", byte)
        }.joined()
        print("result: \(result)")
    } catch let error as Error {
        print("calculation error: \(error.localizedDescription)") // Where is the try, where is the error?
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

这段代码几乎就是您的 MD5 函数以及一些用于测试添加到项目中的文件的代码。

现在,文件的 MD5 有效,但它适用于图像!

我认为 Apple 在图像中添加了一些东西。我打印了 URL 并检查了 - 图片比原始图片小 很多,所以它可能是一些精简版本,删除了所有或大部分元数据,但这只是一个猜测。

无论如何,我分享您的痛苦...Why do these images differ - [img drawInRect:] problem 这里 Apple 更改了您以任意方式绘制的图像。我认为这些调整是为了改进 UI 或 UX,但我个人并不欣赏它们。

您的 md5 功能可以通过 fwiw 工作。但是您应该小心地测试与使用其他 MD5 函数相同的文件。因此,您不应该以任何会改变原始字节的方式对其进行转换。这就是为什么pngData 是个坏主意。但与此同时,我希望如果您将其复制到您的项目中,它会保持不变,但显然不会。

编辑

FWIW,如果您将图像重命名为不带扩展名 png 的名称,然后将其添加到项目中,则它保持不变。我将该图像复制并重命名为z.z,并将其添加到项目中,然后MD5(和z.z)与原始图像相同。

【讨论】:

    猜你喜欢
    • 2012-07-22
    • 2014-05-19
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2013-08-20
    • 2020-12-08
    • 2011-09-12
    相关资源
    最近更新 更多