在Objective-C中,它看起来像这样:
#include <sys/xattr.h> @implementation NSString (reverse) -(NSString*)sha1 { NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding]; uint8_t digest[CC_SHA1_DIGEST_LENGTH]; CC_SHA1(data.bytes, (int)data.length, digest); NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) [output appendFormat:@"%02x", digest[i]]; return output; } @end
我需要Swift这样的东西,可以吗?
请显示工作示例。
您的Objective-C代码(使用NSString类别)可以直接转换为Swift(使用String扩展名)。
NSString
String
首先,您必须创建一个“桥接头”并添加
#import <CommonCrypto/CommonCrypto.h>
然后:
extension String { func sha1() -> String { let data = self.dataUsingEncoding(NSUTF8StringEncoding)! var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0) CC_SHA1(data.bytes, CC_LONG(data.length), &digest) let output = NSMutableString(capacity: Int(CC_SHA1_DIGEST_LENGTH)) for byte in digest { output.appendFormat("%02x", byte) } return output as String } } println("Hello World".sha1())
这可以写得更短和更快速
extension String { func sha1() -> String { let data = self.dataUsingEncoding(NSUTF8StringEncoding)! var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0) CC_SHA1(data.bytes, CC_LONG(data.length), &digest) let hexBytes = map(digest) { String(format: "%02hhx", $0) } return "".join(hexBytes) } }
Swift 2更新:
extension String { func sha1() -> String { let data = self.dataUsingEncoding(NSUTF8StringEncoding)! var digest = [UInt8](count:Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0) CC_SHA1(data.bytes, CC_LONG(data.length), &digest) let hexBytes = digest.map { String(format: "%02hhx", $0) } return hexBytes.joinWithSeparator("") } }
要返回以Base-64编码的字符串而不是十六进制编码的字符串,只需替换
let hexBytes = digest.map { String(format: "%02hhx", $0) } return hexBytes.joinWithSeparator("")
与
return NSData(bytes: digest, length: digest.count).base64EncodedStringWithOptions([])
Swift 3更新:
extension String { func sha1() -> String { let data = self.data(using: String.Encoding.utf8)! var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH)) data.withUnsafeBytes { _ = CC_SHA1($0, CC_LONG(data.count), &digest) } let hexBytes = digest.map { String(format: "%02hhx", $0) } return hexBytes.joined() } }
let hexBytes = digest.map { String(format: "%02hhx", $0) } return hexBytes.joined()
通过
return Data(bytes: digest).base64EncodedString()
Swift 4更新:
不再需要桥接头文件,import CommonCrypto而可以:
import CommonCrypto
import CommonCrypto extension String { func sha1() -> String { let data = Data(self.utf8) var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH)) data.withUnsafeBytes { _ = CC_SHA1($0, CC_LONG(data.count), &digest) } let hexBytes = digest.map { String(format: "%02hhx", $0) } return hexBytes.joined() } }
Swift 5更新:
该Data.withUnsafeBytes()方法现在使用to 调用闭包UnsafeRawBufferPointer,并baseAddress用于将初始地址传递给C函数:
Data.withUnsafeBytes()
UnsafeRawBufferPointer
baseAddress
import CommonCrypto extension String { func sha1() -> String { let data = Data(self.utf8) var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH)) data.withUnsafeBytes { _ = CC_SHA1($0.baseAddress, CC_LONG(data.count), &digest) } let hexBytes = digest.map { String(format: "%02hhx", $0) } return hexBytes.joined() } }