如何在 Swift 中使用 SHA1 散列 NSString? [英] How to hash NSString with SHA1 in Swift?
问题描述
在objective-c中它看起来像这样:
In objective-c it looks like this:
#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 做这样的事情,这可能吗?
I need something like this with Swift, is it possible?
请展示工作示例.
推荐答案
您的 Objective-C 代码(使用 NSString
类别)可以直接转换为 Swift(使用 String
扩展名).
Your Objective-C code (using a NSString
category) can be directly translated to Swift
(using a String
extension).
首先你必须创建一个桥接头"并添加
First you have to create a "bridging header" and add
#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 编码的字符串而不是十六进制编码的字符串,只需替换
To return a Base-64 encoded string instead of a hex encoded string, just replace
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()
}
}
要返回 Base-64 编码的字符串而不是十六进制编码的字符串,只需替换
To return a Base-64 encoded string instead of a hex encoded string, just replace
let hexBytes = digest.map { String(format: "%02hhx", $0) }
return hexBytes.joined()
由
return Data(bytes: digest).base64EncodedString()
Swift 4 更新:
不再需要桥接头文件,可以import CommonCrypto
代替:
The bridging header file is no longer needed, one can import CommonCrypto
instead:
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()
方法现在使用 UnsafeRawBufferPointer
调用闭包,并且 baseAddress
用于将初始地址传递给C函数:
The Data.withUnsafeBytes()
method now calls the closure with an UnsafeRawBufferPointer
to, and baseAddress
is used to pass the initial address to the C function:
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()
}
}
这篇关于如何在 Swift 中使用 SHA1 散列 NSString?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!