在objective-c中,我们可以通过以下代码用md5加密字符串
const char *cStr = [someString UTF8String];
unsigned char result[16];
CC_MD5( cStr, strlen(cStr), result );
md5String = [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]
];
但是现在CC_MD5在swift中不起作用。 如何解决这个问题。
答案 0 :(得分:84)
这就是我想出的。它是String的扩展。
别忘了将#import <CommonCrypto/CommonCrypto.h>
添加到Xcode创建的ObjC-Swift桥接头中。
extension String {
var md5: String! {
let str = self.cStringUsingEncoding(NSUTF8StringEncoding)
let strLen = CC_LONG(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
let digestLen = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
CC_MD5(str!, strLen, result)
let hash = NSMutableString()
for i in 0..<digestLen {
hash.appendFormat("%02x", result[i])
}
result.dealloc(digestLen)
return String(format: hash as String)
}
}
答案 1 :(得分:36)
这是我在Swift 3.0中的版本,我相信它比其他答案更安全,更快。
需要使用#import <CommonCrypto/CommonCrypto.h>
的桥接标头。
func MD5(_ string: String) -> String? {
let length = Int(CC_MD5_DIGEST_LENGTH)
var digest = [UInt8](repeating: 0, count: length)
if let d = string.data(using: String.Encoding.utf8) {
_ = d.withUnsafeBytes { (body: UnsafePointer<UInt8>) in
CC_MD5(body, CC_LONG(d.count), &digest)
}
}
return (0..<length).reduce("") {
$0 + String(format: "%02x", digest[$1])
}
}
答案 2 :(得分:10)
我将纯粹的Swift实现MD5作为CryptoSwift项目的一部分。
我可以在这里复制代码,但它使用属于此项目一部分的扩展,因此对于复制和粘贴使用可能没用。但是你可以看看并使用它。
答案 3 :(得分:6)
<强> BridgingHeader 强> - &gt;用于将Objective-c代码暴露给Swift项目
<强> CommonCrypto 强> - &gt;是使用 md5哈希
所需的文件由于Common Crypto是一个Objective-c文件,你需要使用BridgingHeader来使用散列所需的方法
(例如)
anotations
}
如何将Common Crypto添加到Swift项目中?
这link将教你如何(逐步)。
我建议使用桥接标题
*************更新了Swift 3 ****************
extension String {
func md5() -> String! {
let str = self.cStringUsingEncoding(NSUTF8StringEncoding)
let strLen = CUnsignedInt(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
let digestLen = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
CC_MD5(str!, strLen, result)
var hash = NSMutableString()
for i in 0..<digestLen {
hash.appendFormat("%02x", result[i])
}
result.destroy()
return String(format: hash as String)
}
如何使用?
让stringConvertedToMD5 =“foo”.toMD5()
答案 4 :(得分:2)
如果你想从NSData中计算出MD5,请看一下:
func md5() -> NSData {
var ctx = UnsafePointer<CC_MD5_CTX>.alloc(sizeof(CC_MD5_CTX))
CC_MD5_Init(ctx);
CC_MD5_Update(ctx, self.bytes, UInt32(self.length));
let length = Int(CC_MD5_DIGEST_LENGTH) * sizeof(Byte)
var output = UnsafePointer<Byte>.alloc(length)
CC_MD5_Final(output, ctx);
let outData = NSData(bytes: output, length: Int(CC_MD5_DIGEST_LENGTH))
output.destroy()
ctx.destroy()
//withUnsafePointer
return outData;
}
得到主意。
答案 5 :(得分:2)
Xcode 6 beta 5 现在使用UnsafeMutablePointer
代替UnsafePointer
。字符串转换还需要format:
参数标签。
extension String {
func md5() -> String! {
let str = self.cStringUsingEncoding(NSUTF8StringEncoding)
let strLen = CUnsignedInt(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
let digestLen = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
CC_MD5(str!, strLen, result)
var hash = NSMutableString()
for i in 0..<digestLen {
hash.appendFormat("%02x", result[i])
}
result.destroy()
return String(format: hash)
}
}
答案 6 :(得分:2)
需要将导入#import <CommonCrypto/CommonCrypto.h>
导入桥接标题
我正在计算MD5哈希,但只使用我正在使用的前16个字节
class func hash(data: NSData) -> String {
let data2 = NSMutableData(length: Int(CC_MD5_DIGEST_LENGTH))!
CC_MD5(data.bytes, CC_LONG(data.length), UnsafeMutablePointer<UInt8>(data2.mutableBytes))
let data3 = UnsafePointer<CUnsignedChar>(data2.bytes)
var hash = ""
for (var i = 0; i < 16; ++i) {
hash += String(format: "%02X", data3[i])
}
return hash
}
答案 7 :(得分:2)
对于桥接标题不是选项的情况(例如,在shell脚本中),您可以通过+;-
使用命令行工具/sbin/md5
:
NSTask
用法:
import Foundation
func md5hash(string: String) -> String
{
let t = NSTask()
t.launchPath = "/sbin/md5"
t.arguments = ["-q", "-s", string]
t.standardOutput = NSPipe()
t.launch()
let outData = t.standardOutput.fileHandleForReading.readDataToEndOfFile()
var outBytes = [UInt8](count:outData.length, repeatedValue:0)
outData.getBytes(&outBytes, length: outData.length)
var outString = String(bytes: outBytes, encoding: NSASCIIStringEncoding)
assert(outString != nil, "failed to md5 input string")
return outString!.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet())
}
答案 8 :(得分:1)
为了使它在Swift 5中正常工作,我必须对此代码进行一些修复
func md5(inString: String) -> String! {
let str = inString.cString(using: String.Encoding.utf8)
let strLen = CUnsignedInt(inString.lengthOfBytes(using: String.Encoding.utf8))
let digestLen = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
CC_MD5(str!, strLen, result)
var hash = NSMutableString()
for i in 0..<digestLen {
hash.appendFormat("%02x", result[i])
}
result.deallocate()
return String(format: hash as String)
}