Swift 4 iOS应用中如何生成无BOM无末尾0字节UTF16LE的MD5?
解决Swift 4 iOS中生成UTF16LE(无BOM、无末尾0字节)的MD5哈希问题
我太懂这种卡壳的感觉了——要复刻C#那边特定编码下的MD5结果,差一点都不行,之前试了各种常规方案都踩坑对吧?别着急,咱们针对UTF-16LE无BOM、无末尾0字节这个核心要求,来写精准的实现:
方法一:用系统CommonCrypto框架实现(无需第三方库)
直接手动处理编码字节,确保完全符合要求:
import CommonCrypto func generateMD5ForUTF16LE(_ input: String) -> String? { // 获取字符串的UTF-16编码单元(无额外终止符) let utf16Units = input.utf16 // 将每个UTF-16单元拆分为小端字节(UTF16LE格式) var rawBytes = [UInt8]() for unit in utf16Units { rawBytes.append(UInt8(unit & 0xFF)) // 低字节(小端优先) rawBytes.append(UInt8(unit >> 8)) // 高字节 } // 计算MD5哈希 var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH)) CC_MD5(rawBytes, CC_LONG(rawBytes.count), &digest) // 转换为十六进制字符串返回 return digest.map { String(format: "%02x", $0) }.joined() }
关键说明:
- 直接遍历字符串的
utf16属性,不会自动添加末尾的0终止符 - 手动拆分每个UTF-16单元为小端字节,完全匹配UTF16LE编码规则,且无BOM(字节顺序标记)
方法二:用CryptoSwift库的正确姿势
如果你更倾向用第三方库,之前没成功大概率是编码参数没选对,试试这个:
import CryptoSwift func generateMD5WithCryptoSwift(_ input: String) -> String? { // 直接用UTF16LittleEndian编码生成Data,无BOM、无终止符 guard let utf16LEData = input.data(using: .utf16LittleEndian, allowLossyConversion: false) else { return nil } do { let md5Bytes = try MD5().calculate(for: utf16LEData.bytes) return md5Bytes.toHexString() } catch { print("MD5计算失败:\(error)") return nil } }
关键说明:
- 一定要指定
.utf16LittleEndian编码,这个编码会直接生成符合要求的UTF16LE字节流,既不会添加BOM,也不会自动追加末尾的0终止符 - 避免用默认的
utf16编码(它会带BOM),这是之前很多人踩坑的点
验证建议
找一个测试字符串,比如"HelloWorld",同时用C#的目标代码和上面的Swift代码生成哈希,对比结果是否一致——如果还是有差异,检查下是否在C#端处理时有没有额外的字节操作,比如是否真的完全移除了末尾0字节。
内容的提问来源于stack exchange,提问作者Sergej D.
相关产品推荐
相关产品推荐

