SHA256在迅速

Yur*_*rov 63 sha256 swift

我想在我的项目中使用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无法转换IntCC_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)

  • 我怎么能将这个nsdata转换为字符串,因为它是我试图转换它给我错误的值 (4认同)
  • 作为此解决方案的补充,要在Swift中进行CC_SHA256_DIGEST_LENGTH,CC_SHA256和CC_LONG工作,您必须在桥接头文件中添加#import <CommonCrypto / CommonDigest.h>。 (3认同)
  • 您的Swift 5示例已过时。 (2认同)

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的桥接头.如果您没有,请按照以下步骤操作:

  1. 创建新文件 - >头文件 - >另存为 BridgingHeader
  2. 在构建设置 - > Objective-C桥接标题 - >添加 ProjectName/BridgingHeader.h
  3. 放入#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

  • @KevinRenskers 使用可以使用 `#if canImport(CryptoKit)` 进行条件导入。不要忘记在“其他链接器标志”中设置“-weak_framework CryptoKit” (2认同)

zer*_*nna 8

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)


dua*_*uan 6

随着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,比如SHA384DigestSHA512DigestSHA1DigestMD5Digest...


Nic*_*ore 5

这是我使用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)

  • 直到我看不到iOS的热爱,这看起来都很棒。 (7认同)