Swift 4でハッシュ値の計算(MD5, SHA1, SHA256, etc.)

忘れそう・・・

そもそもコピペコードを理解しないと

Swift 4で動作するように若干書き直し。

CommonCrypto を使うため、事前に BridgingHeader の下準備が必要です。(過去記事参照)

Amazon API 叩くのに HMAC-SHA256 が必要でその過程の部分のメモ。 極力他ライブラリを使わない方向。CryptoS...

以下コード。計算結果は別の方法で検算してください;

実際に必要なのは SHA1 だけとか SHA256 だけとかと思うので以下は参考程度にですが。

import Foundation

enum CryptoAlgorithm {
    case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
    
    var digestLength: Int {
        var result: Int32 = 0
        switch self {
        case .MD5:      result = CC_MD5_DIGEST_LENGTH
        case .SHA1:     result = CC_SHA1_DIGEST_LENGTH
        case .SHA224:   result = CC_SHA224_DIGEST_LENGTH
        case .SHA256:   result = CC_SHA256_DIGEST_LENGTH
        case .SHA384:   result = CC_SHA384_DIGEST_LENGTH
        case .SHA512:   result = CC_SHA512_DIGEST_LENGTH
        }
        return Int(result)
    }
}
extension String {
    var md5:    String { return digest(string: self, algorithm: .MD5) }
    var sha1:   String { return digest(string: self, algorithm: .SHA1) }
    var sha224: String { return digest(string: self, algorithm: .SHA224) }
    var sha256: String { return digest(string: self, algorithm: .SHA256) }
    var sha384: String { return digest(string: self, algorithm: .SHA384) }
    var sha512: String { return digest(string: self, algorithm: .SHA512) }

    func digest(string: String, algorithm: CryptoAlgorithm) -> String {
        var result: [CUnsignedChar]
        let digestLength = Int(algorithm.digestLength)
        if let cdata = string.cString(using: String.Encoding.utf8) {
            result = Array(repeating: 0, count: digestLength)
            switch algorithm {
            case .MD5:      CC_MD5(cdata, CC_LONG(cdata.count-1), &result)
            case .SHA1:     CC_SHA1(cdata, CC_LONG(cdata.count-1), &result)
            case .SHA224:   CC_SHA224(cdata, CC_LONG(cdata.count-1), &result)
            case .SHA256:   CC_SHA256(cdata, CC_LONG(cdata.count-1), &result)
            case .SHA384:   CC_SHA384(cdata, CC_LONG(cdata.count-1), &result)
            case .SHA512:   CC_SHA512(cdata, CC_LONG(cdata.count-1), &result)
            }
        } else {
            fatalError("Nil returned when processing input strings as UTF8")
        }
        return (0..<digestLength).reduce("") { $0 + String(format: "%02hhx", result[$1])}
    }
}


呼び出し側

let text = "foo bar buz"
print("   MD5: \(text.md5)")
print("  SHA1: \(text.sha1)")
print("SHA224: \(text.sha224)")
print("SHA256: \(text.sha256)")
print("SHA384: \(text.sha384)")
print("SHA512: \(text.sha512)")

実行結果

   MD5: 0844c8a9954059836ec1e494fccddb5f
  SHA1: 4510a64548a57d900a517628b9c132738c4a4a15
SHA224: 95544f973183821c0172e4d0402e207526e9fe5442098cb88bfa9889
SHA256: 004467f99020d53e57fb79a99bcb8fd5ee646a2bb8542f0110266d796acbd665
SHA384: 83f37298e4b20785e1f77467399545629f24b400e46a27e5b7aa50dc4cf969791a4a31b84927ef464ac6181804f41223
SHA512: 7c60bc750a0cbce5f42c234866f06b9b23575f687876d710f3a3c23282f66b07f545c4b4bb7fee0d76d3183556498c6ed03cb4eb8bec9b9d1972e041cd054343

Mac でコマンドラインからハッシュ値を計算する(SHA1検算例)

$ echo -n "foo bar buz" | openssl sha1

と思ったら openssl では MD5 と SHA1 しか検算できない、、のかな?(そんなことはない気もするけど)

参考サイト:

Swift3でStringをMD5文字列に変換する時に得たことのメモ

HMAC SHA512 using CommonCrypto in Swift 3.1 [duplicate]

Array.init(repeating:count:) (公式)

フォローする