enum HMACAlgorithm { case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
func toCCHmacAlgorithm() -> CCHmacAlgorithm { var result: Int = 0 switchself { case .MD5: result = kCCHmacAlgMD5 case .SHA1: result = kCCHmacAlgSHA1 case .SHA224: result = kCCHmacAlgSHA224 case .SHA256: result = kCCHmacAlgSHA256 case .SHA384: result = kCCHmacAlgSHA384 case .SHA512: result = kCCHmacAlgSHA512 } return CCHmacAlgorithm(result) }
func digestLength() -> Int { var result: CInt = 0 switchself { case .MD5: result = CC_MD5_DIGEST_LENGTH case .SHA1: result = CC_SHA1_DIGEST_LENGTH case .SHA224: result = CC_SHA224_DIGEST_LENGTH case .SHA256: result = CC_SHA256_DIGEST_LENGTH case .SHA384: result = CC_SHA384_DIGEST_LENGTH case .SHA512: result = CC_SHA512_DIGEST_LENGTH } return Int(result) } }
extension String { func hmac(algorithm: HMACAlgorithm, key: String) -> String { let cKey = key.cStringUsingEncoding(NSUTF8StringEncoding) let cData = self.cStringUsingEncoding(NSUTF8StringEncoding) var result = [CUnsignedChar](count: Int(algorithm.digestLength()), repeatedValue: 0) CCHmac(algorithm.toCCHmacAlgorithm(), cKey!, strlen(cKey!), cData!, strlen(cData!), &result) var hmacData:NSData = NSData(bytes: result, length: (Int(algorithm.digestLength()))) var hmacBase64 = hmacData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.Encoding76CharacterLineLength) return String(hmacBase64) } }
///字符直接转 md5 funcconversionToMD5() -> String { let str =self.cString(using: String.Encoding.utf8) let strLen =CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8)) let digestLen =Int(CC_MD5_DIGEST_LENGTH) let result =UnsafeMutablePointer<UInt8>.allocate(capacity: 16) CC_MD5(str!, strLen, result) let hash =NSMutableString() for i in0..< digestLen { hash.appendFormat("%02x", result[i]) } free(result) returnString(format: hash asString) }
所以步骤分为以下两步: 1.把 String 类型数据转换成 16 进制 Data 数据——注意是 16 进制的 Data 数据,如果直接用原生方法 "<#String#>".(using: .utf8) 转换肯定是不行的。 2.把 Data 数据丢进 MD5 方法中进行加密 而在网上搜了一圈,Swift 版本大部分看到的都是用字符串进行 MD5 加密,最后仍是在 Stack Overflow 上看到了一个正确的结果 - MD5 of Data in Swift 3
///转换成 Data 数据再转换成 md5 funcconversionToDataToMD5() -> String{ let data =Data(hex: self) var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
data.withUnsafeBytes { CC_MD5($0.baseAddress, UInt32(data.count), &digest) } var hashString ="" for byte in digest { hashString +=String(format:"%02x", UInt8(byte)) }
extensionArray { publicinit(reserveCapacity: Int) { self=Array<Element>() self.reserveCapacity(reserveCapacity) } } extensionArraywhereElement==UInt8 { publicinit(hex: String) { self.init(reserveCapacity: hex.unicodeScalars.lazy.underestimatedCount) var buffer: UInt8? var skip = hex.hasPrefix("0x") ?2 : 0 for char in hex.unicodeScalars.lazy { guard skip ==0else { skip -=1 continue } guard char.value >=48&& char.value <=102else { removeAll() return } let v: UInt8 let c: UInt8=UInt8(char.value) switch c { caselet c where c <=57: v = c -48 caselet c where c >=65&& c <=70: v = c -55 caselet c where c >=97: v = c -87 default: removeAll() return } iflet b = buffer { append(b <<4| v) buffer =nil } else { buffer = v } } iflet b = buffer { append(b) } } }
使用:
1
let md5Str ="两个黄鹂鸣翠柳,一行白鹭上青天。".conversionToDataToMD5()