我想在我的项目中使用sha256,但是我有一些麻烦将objC代码重写为swift代码.请帮帮我.我使用了这个答案:如何在iOS中计算SHA-2(理想情况为SHA 256或SHA 512)哈希?
这是我的代码
var hash : [CUnsignedChar]
CC_SHA256(data.bytes, data.length, hash)
var res : NSData = NSData.dataWithBytes(hash, length: CC_SHA256_DIGEST_LENGTH)
Run Code Online (Sandbox Code Playgroud)
它给了我错误的一切,因为swift无法转换Int为CC_LONG,例如.
Mar*_*n R 98
你必须在Int和之间显CC_LONG式转换,因为Swift不进行隐式转换,如(Objective-)C.
您还必须定义hash为所需大小的数组.
func sha256(data : NSData) -> NSData {
var hash = [UInt8](count: Int(CC_SHA256_DIGEST_LENGTH), repeatedValue: 0)
CC_SHA256(data.bytes, CC_LONG(data.length), &hash)
let res = NSData(bytes: hash, length: Int(CC_SHA256_DIGEST_LENGTH))
return res
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用NSMutableData分配所需的缓冲区:
func sha256(data : NSData) -> NSData {
let res = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH))
CC_SHA256(data.bytes, CC_LONG(data.length), UnsafeMutablePointer(res.mutableBytes))
return res
}
Run Code Online (Sandbox Code Playgroud)
Swift 3更新:
func sha256(data : Data) -> Data {
var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
data.withUnsafeBytes {
_ = CC_SHA256($0, CC_LONG(data.count), &hash)
}
return Data(bytes: hash)
}
Run Code Online (Sandbox Code Playgroud)
And*_*eas 64
最佳答案对我不起作用.我在网上发现了一些东西,并稍微改了一下,现在它有效:D.它适用于Swift 3和4.
将此扩展名放在项目中的某个位置,并将其用于如下字符串:mystring.sha256()
extension String {
func sha256() -> String{
if let stringData = self.data(using: String.Encoding.utf8) {
return hexStringFromData(input: digest(input: stringData as NSData))
}
return ""
}
private func digest(input : NSData) -> NSData {
let digestLength = Int(CC_SHA256_DIGEST_LENGTH)
var hash = [UInt8](repeating: 0, count: digestLength)
CC_SHA256(input.bytes, UInt32(input.length), &hash)
return NSData(bytes: hash, length: digestLength)
}
private func hexStringFromData(input: NSData) -> String {
var bytes = [UInt8](repeating: 0, count: input.length)
input.getBytes(&bytes, length: input.length)
var hexString = ""
for byte in bytes {
hexString += String(format:"%02x", UInt8(byte))
}
return hexString
}
}
Run Code Online (Sandbox Code Playgroud)
顺便说一下,你需要一个导入CommonCrypto的桥接头.如果您没有,请按照以下步骤操作:
BridgingHeaderProjectName/BridgingHeader.h#import <CommonCrypto/CommonHMAC.h>你的头文件Gra*_*rks 15
从NSData&String(Swift 3)给出SHA的函数:
func sha256(_ data: Data) -> Data? {
guard let res = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH)) else { return nil }
CC_SHA256((data as NSData).bytes, CC_LONG(data.count), res.mutableBytes.assumingMemoryBound(to: UInt8.self))
return res as Data
}
func sha256(_ str: String) -> String? {
guard
let data = str.data(using: String.Encoding.utf8),
let shaData = sha256(data)
else { return nil }
let rc = shaData.base64EncodedString(options: [])
return rc
}
Run Code Online (Sandbox Code Playgroud)
包含在您的桥接标题中:
#import "CommonCrypto/CommonCrypto.h"
Run Code Online (Sandbox Code Playgroud)
Ral*_*ert 13
在 iOS 13 上使用 CryptoKit 的 Swift 5 版本,否则回退到 CommonCrypto:
import CommonCrypto
import CryptoKit
import Foundation
private func hexString(_ iterator: Array<UInt8>.Iterator) -> String {
return iterator.map { String(format: "%02x", $0) }.joined()
}
extension Data {
public var sha256: String {
if #available(iOS 13.0, *) {
return hexString(SHA256.hash(data: self).makeIterator())
} else {
var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
self.withUnsafeBytes { bytes in
_ = CC_SHA256(bytes.baseAddress, CC_LONG(self.count), &digest)
}
return hexString(digest.makeIterator())
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
let string = "The quick brown fox jumps over the lazy dog"
let hexDigest = string.data(using: .ascii)!.sha256
assert(hexDigest == "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592")
Run Code Online (Sandbox Code Playgroud)
也可以通过 Swift 包管理器获得:https :
//github.com/ralfebert/TinyHashes
import CommonCrypto
public extension String {
var sha256: String {
let data = Data(utf8)
var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
data.withUnsafeBytes { buffer in
_ = CC_SHA256(buffer.baseAddress, CC_LONG(buffer.count), &hash)
}
return hash.map { String(format: "%02hhx", $0) }.joined()
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
我研究了很多答案,我总结了一下:
import CryptoKit
import CommonCrypto
Run Code Online (Sandbox Code Playgroud)
extension String {
func hash256() -> String {
let inputData = Data(utf8)
if #available(iOS 13.0, *) {
let hashed = SHA256.hash(data: inputData)
return hashed.compactMap { String(format: "%02x", $0) }.joined()
} else {
var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
inputData.withUnsafeBytes { bytes in
_ = CC_SHA256(bytes.baseAddress, UInt32(inputData.count), &digest)
}
return digest.makeIterator().compactMap { String(format: "%02x", $0) }.joined()
}
}
}
Run Code Online (Sandbox Code Playgroud)
随着CryptoKit在iOS13补充说,我们现在有原生API斯威夫特:
import Foundation
import CryptoKit
// CryptoKit.Digest utils
extension Digest {
var bytes: [UInt8] { Array(makeIterator()) }
var data: Data { Data(bytes) }
var hexStr: String {
bytes.map { String(format: "%02X", $0) }.joined()
}
}
func example() {
guard let data = "hello world".data(using: .utf8) else { return }
let digest = SHA256.hash(data: data)
print(digest.data) // 32 bytes
print(digest.hexStr) // B94D27B9934D3E08A52E52D7DA7DABFAC484EFE37A5380EE9088F7ACE2EFCDE9
}
Run Code Online (Sandbox Code Playgroud)
由于utils的是为协议定义Digest,你可以用它在所有摘要类型CryptoKit,比如SHA384Digest,SHA512Digest,SHA1Digest,MD5Digest...
这是我使用Security Transforms API的简单的3行Swift 4函数,它是macOS上Foundation的一部分。(不幸的是,iOS程序员无法使用此技术。)
import Foundation
extension Data {
public func sha256Hash() -> Data {
let transform = SecDigestTransformCreate(kSecDigestSHA2, 256, nil)
SecTransformSetAttribute(transform, kSecTransformInputAttributeName, self as CFTypeRef, nil)
return SecTransformExecute(transform, nil) as! Data
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
45042 次 |
| 最近记录: |