SHA256在迅速
我想在我的项目中使用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)
它给了我错误的一切,因为swift不能将Int
转换为CC_LONG
,例如。
您必须在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 }
或者,您可以使用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 }
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) }
最重要的答案不适合我。 我在网上发现了一些东西,然后改变了一下,现在它可以正常工作了。 这是斯威夫特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 } }
顺便说一下,您需要一个导入CommonCrypto的桥接头。 如果您没有一个请按照下列步骤操作:
- 创build新的文件 – >头文件 – >另存为
BridgingHeader
- 在生成设置 – > Objective-C桥接头 – >添加
ProjectName/BridgingHeader.h
- 将
#import <CommonCrypto/CommonHMAC.h>
放在头文件中
从NSData
& String
给出SHA的函数(Swift 3):
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 }
包含在您的桥接头中:
#import "CommonCrypto/CommonCrypto.h"
这是一个使用CoreFoundation安全性转换API的方法,所以你甚至不需要链接到CommonCrypto。 出于某种原因10.10 / Xcode 7与Swift连接到CommmonCrypto是戏剧,所以我用这个来代替。
这个方法从一个NSInputStream
读取,你可以从一个文件中获得NSInputStream
,或者你可以创build一个NSData
,或者你可以为一个缓冲进程创build绑定的读写器stream。
// digestType is from SecDigestTransform and would be kSecDigestSHA2, etc func digestForStream(stream : NSInputStream, digestType type : CFStringRef, length : Int) throws -> NSData { let transform = SecTransformCreateGroupTransform().takeRetainedValue() let readXform = SecTransformCreateReadTransformWithReadStream(stream as CFReadStreamRef).takeRetainedValue() var error : Unmanaged<CFErrorRef>? = nil let digestXform : SecTransformRef = try { let d = SecDigestTransformCreate(type, length, &error) if d == nil { throw error!.takeUnretainedValue() } else { return d.takeRetainedValue() } }() SecTransformConnectTransforms(readXform, kSecTransformOutputAttributeName, digestXform, kSecTransformInputAttributeName, transform, &error) if let e = error { throw e.takeUnretainedValue() } if let output = SecTransformExecute(transform, &error) as? NSData { return output } else { throw error!.takeUnretainedValue() } }