itsource

Swift를 사용하여 iOS에서 문자열을 MD5 해시로 변환하려면 어떻게 해야 합니까?

mycopycode 2023. 4. 22. 09:27
반응형

Swift를 사용하여 iOS에서 문자열을 MD5 해시로 변환하려면 어떻게 해야 합니까?

"abc"와 같은 문자열을 MD5 해시로 변환합니다.iOS와 Swift에서 하고 싶다.아래 솔루션을 사용해 보았지만, 효과가 없었습니다.

Swift 프레임워크에서의 CommonCrypto Import

CC_MD5 메서드를 스위프트 언어로 사용하는 방법.

http://iosdeveloperzone.com/2014/10/03/using-commoncrypto-in-swift/

좀 더 명확하게 하기 위해, 나는 이 PHP 코드의 출력과 유사한 Swift 출력을 얻고 싶다.

$str = "Hello";

echo md5($str);

출력: 8b1a9953c4611296a827abf8c47804d7

을 하다
. 'md5'
2. md5 16으로 변환합니다.

Swift 2.0:

func md5(string string: String) -> String {
    var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
    if let data = string.dataUsingEncoding(NSUTF8StringEncoding) {
        CC_MD5(data.bytes, CC_LONG(data.length), &digest)
    }

    var digestHex = ""
    for index in 0..<Int(CC_MD5_DIGEST_LENGTH) {
        digestHex += String(format: "%02x", digest[index])
    }

    return digestHex
}

//Test:
let digest = md5(string:"Hello")
print("digest: \(digest)")

출력:

다이제스트: 8b1a9953c4611296a827abf8c47804d7

Swift 3.0:

func MD5(string: String) -> Data {
    let messageData = string.data(using:.utf8)!
    var digestData = Data(count: Int(CC_MD5_DIGEST_LENGTH))

    _ = digestData.withUnsafeMutableBytes {digestBytes in
        messageData.withUnsafeBytes {messageBytes in
            CC_MD5(messageBytes, CC_LONG(messageData.count), digestBytes)
        }
    }

    return digestData
}

//Test:
let md5Data = MD5(string:"Hello")

let md5Hex =  md5Data.map { String(format: "%02hhx", $0) }.joined()
print("md5Hex: \(md5Hex)")

let md5Base64 = md5Data.base64EncodedString()
print("md5Base64: \(md5Base64)")

출력:

md516 진수: 8b1a9953c4611296a827abf8c47804d7
md5Base64: ixqZU8RhEpaoJ6v4xHgE1w==

Swift 5.0:

import Foundation
import var CommonCrypto.CC_MD5_DIGEST_LENGTH
import func CommonCrypto.CC_MD5
import typealias CommonCrypto.CC_LONG

func MD5(string: String) -> Data {
        let length = Int(CC_MD5_DIGEST_LENGTH)
        let messageData = string.data(using:.utf8)!
        var digestData = Data(count: length)

        _ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in
            messageData.withUnsafeBytes { messageBytes -> UInt8 in
                if let messageBytesBaseAddress = messageBytes.baseAddress, let digestBytesBlindMemory = digestBytes.bindMemory(to: UInt8.self).baseAddress {
                    let messageLength = CC_LONG(messageData.count)
                    CC_MD5(messageBytesBaseAddress, messageLength, digestBytesBlindMemory)
                }
                return 0
            }
        }
        return digestData
    }

//Test:
let md5Data = MD5(string:"Hello")

let md5Hex =  md5Data.map { String(format: "%02hhx", $0) }.joined()
print("md5Hex: \(md5Hex)")

let md5Base64 = md5Data.base64EncodedString()
print("md5Base64: \(md5Base64)")

출력:

md516 진수: 8b1a9953c4611296a827abf8c47804d7
md5Base64: ixqZU8RhEpaoJ6v4xHgE1w==

★★★★★★★
#import <CommonCrypto/CommonCrypto.h> 파일에.

브리징 헤더의 작성 방법에 대해서는, 다음의 SO 답변을 참조해 주세요.

일반적으로 MD5는 새로운 작업에 사용하지 않는 것이 좋습니다.SHA256은 현재의 베스트 프랙티스입니다.

폐지된 문서 섹션의 예:

MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384, SHA512 (스위프트3+)

이러한 함수는 String 또는 Data 입력을 8개의 암호화 해시 알고리즘 중 하나로 해시합니다.

합니다.
및 이에서는 Common 합니다.MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384 SHA512 。공통 암호
프로젝트에 대한 브리징헤더가 필요합니다.
#import <CommonCrypto/CommonCrypto.h>
Security.framework 를 security security 。



이 함수는 해시할 해시 이름과 문자열을 가져와서 데이터를 반환합니다.

name : 문자열로서의 해시함수 이름string : 해시되는 문자열반환: 해시된 결과를 데이터로 반환
func hash(name:String, string:String) -> Data? {
    let data = string.data(using:.utf8)!
    return hash(name:name, data:data)
}

예:

let clearString = "clearData0123456"
let clearData   = clearString.data(using:.utf8)!
print("clearString: \(clearString)")
print("clearData: \(clearData as NSData)")

let hashSHA256 = hash(name:"SHA256", string:clearString)
print("hashSHA256: \(hashSHA256! as NSData)")

let hashMD5 = hash(name:"MD5", data:clearData)
print("hashMD5: \(hashMD5! as NSData)")

출력:

clearString: clearData0123456
clearData: <636c6561 72446174 61303132 33343536>

hashSHA256: <aabc766b 6b357564 e41f4f91 2d494bcc bfa16924 b574abbd ba9e3e9d a0c8920a>
hashMD5: <4df665f7 b94aea69 695b0e7b baf9e9d6>

iOS 13에서 Apple은 CommonCrypto를 Import하거나 C API를 처리할 필요가 없도록 프레임워크를 추가했습니다.

import Foundation
import CryptoKit

func MD5(string: String) -> String {
    let digest = Insecure.MD5.hash(data: Data(string.utf8))

    return digest.map {
        String(format: "%02hhx", $0)
    }.joined()
}
 

여기서의 다른 답변을 읽고(다른 해시 타입도 지원해야 함) 여러 해시 타입과 출력 타입을 처리하는 문자열 확장자를 작성했습니다.

메모:10에 되어 있기 에, 「: CommonCrypto」Xcode 10을 사용할 수 .import CommonCrypto최신 Xcode 버전이 설치되어 있는 경우 브리징헤더를 조작할 필요가 없습니다.그렇지 않으면 브리징헤더가 필요합니다.


업데이트: Swift 4와 5 모두 아래의 String+Crypto.swift 파일을 사용합니다.

Swift 4와 5 사이에서 'with Unsafe Mutable Bytes'와 'with Unsafe Bytes'의 API가 변경되어 Swift 5용 Data+Crypto.swift 파일이 별도로 있습니다.


String+Crypto.swift -- (Swift 4 및 5 모두)

import Foundation
import CommonCrypto

// Defines types of hash string outputs available
public enum HashOutputType {
    // standard hex string output
    case hex
    // base 64 encoded string output
    case base64
}

// Defines types of hash algorithms available
public enum HashType {
    case md5
    case sha1
    case sha224
    case sha256
    case sha384
    case sha512

    var length: Int32 {
        switch self {
        case .md5: return CC_MD5_DIGEST_LENGTH
        case .sha1: return CC_SHA1_DIGEST_LENGTH
        case .sha224: return CC_SHA224_DIGEST_LENGTH
        case .sha256: return CC_SHA256_DIGEST_LENGTH
        case .sha384: return CC_SHA384_DIGEST_LENGTH
        case .sha512: return CC_SHA512_DIGEST_LENGTH
        }
    }
}

public extension String {

    /// Hashing algorithm for hashing a string instance.
    ///
    /// - Parameters:
    ///   - type: The type of hash to use.
    ///   - output: The type of output desired, defaults to .hex.
    /// - Returns: The requested hash output or nil if failure.
    public func hashed(_ type: HashType, output: HashOutputType = .hex) -> String? {

        // convert string to utf8 encoded data
        guard let message = data(using: .utf8) else { return nil }
        return message.hashed(type, output: output)
    } 
}

SWIFT 5 -- Data + Crypto . swift

import Foundation
import CommonCrypto

extension Data {

    /// Hashing algorithm that prepends an RSA2048ASN1Header to the beginning of the data being hashed.
    ///
    /// - Parameters:
    ///   - type: The type of hash algorithm to use for the hashing operation.
    ///   - output: The type of output string desired.
    /// - Returns: A hash string using the specified hashing algorithm, or nil.
    public func hashWithRSA2048Asn1Header(_ type: HashType, output: HashOutputType = .hex) -> String? {

        let rsa2048Asn1Header:[UInt8] = [
            0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
            0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00
        ]

        var headerData = Data(rsa2048Asn1Header)
        headerData.append(self)

        return hashed(type, output: output)
    }

    /// Hashing algorithm for hashing a Data instance.
    ///
    /// - Parameters:
    ///   - type: The type of hash to use.
    ///   - output: The type of hash output desired, defaults to .hex.
    ///   - Returns: The requested hash output or nil if failure.
    public func hashed(_ type: HashType, output: HashOutputType = .hex) -> String? {

        // setup data variable to hold hashed value
        var digest = Data(count: Int(type.length))

        _ = digest.withUnsafeMutableBytes{ digestBytes -> UInt8 in
            self.withUnsafeBytes { messageBytes -> UInt8 in
                if let mb = messageBytes.baseAddress, let db = digestBytes.bindMemory(to: UInt8.self).baseAddress {
                    let length = CC_LONG(self.count)
                    switch type {
                    case .md5: CC_MD5(mb, length, db)
                    case .sha1: CC_SHA1(mb, length, db)
                    case .sha224: CC_SHA224(mb, length, db)
                    case .sha256: CC_SHA256(mb, length, db)
                    case .sha384: CC_SHA384(mb, length, db)
                    case .sha512: CC_SHA512(mb, length, db)
                    }
                }
                return 0
            }
        }

        // return the value based on the specified output type.
        switch output {
        case .hex: return digest.map { String(format: "%02hhx", $0) }.joined()
        case .base64: return digest.base64EncodedString()
        }
    }
}

SWIFT 4 -- Data+Crypto.swift

import Foundation
import CommonCrypto 

extension Data {

    /// Hashing algorithm that prepends an RSA2048ASN1Header to the beginning of the data being hashed.
    ///
    /// - Parameters:
    ///   - type: The type of hash algorithm to use for the hashing operation.
    ///   - output: The type of output string desired.
    /// - Returns: A hash string using the specified hashing algorithm, or nil.
    public func hashWithRSA2048Asn1Header(_ type: HashType, output: HashOutputType = .hex) -> String? {

        let rsa2048Asn1Header:[UInt8] = [
            0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
            0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00
        ]

        var headerData = Data(bytes: rsa2048Asn1Header)
        headerData.append(self)

        return hashed(type, output: output)
    }

    /// Hashing algorithm for hashing a Data instance.
    ///
    /// - Parameters:
    ///   - type: The type of hash to use.
    ///   - output: The type of hash output desired, defaults to .hex.
    ///   - Returns: The requested hash output or nil if failure.
    public func hashed(_ type: HashType, output: HashOutputType = .hex) -> String? {

        // setup data variable to hold hashed value
        var digest = Data(count: Int(type.length))

        // generate hash using specified hash type
        _ = digest.withUnsafeMutableBytes { (digestBytes: UnsafeMutablePointer<UInt8>) in
            self.withUnsafeBytes { (messageBytes: UnsafePointer<UInt8>) in
                let length = CC_LONG(self.count)
                switch type {
                case .md5: CC_MD5(messageBytes, length, digestBytes)
                case .sha1: CC_SHA1(messageBytes, length, digestBytes)
                case .sha224: CC_SHA224(messageBytes, length, digestBytes)
                case .sha256: CC_SHA256(messageBytes, length, digestBytes)
                case .sha384: CC_SHA384(messageBytes, length, digestBytes)
                case .sha512: CC_SHA512(messageBytes, length, digestBytes)
                }
            }
        }

        // return the value based on the specified output type.
        switch output {
        case .hex: return digest.map { String(format: "%02hhx", $0) }.joined()
        case .base64: return digest.base64EncodedString()
        }
    }
}

편집: 해시는 실제로 데이터에서 발생하므로 해시 알고리즘을 데이터 확장자로 분할합니다.이것에 의해, SSL 증명서의 핀 접속 해시 조작에도 같은 알고리즘을 사용할 수 있습니다.

SSL 핀 접속 조작에 사용하는 간단한 예를 다음에 나타냅니다.

// Certificate pinning - get certificate as data
let data: Data = SecCertificateCopyData(serverCertificate) as Data

// compare hash of server certificate with local (expected) hash value
guard let serverHash = data.hashWithRSA2048Asn1Header(.sha256, output: .base64), serverHash == storedHash else {
    print("SSL PINNING: Server certificate hash does not match specified hash value.")
    return false
}

원답으로 되돌아가다

다음을 사용하여 해시 알고리즘을 테스트했습니다.

let value = "This is my string"

if let md5 = value.hashed(.md5) {
    print("md5: \(md5)")
}
if let sha1 = value.hashed(.sha1) {
    print("sha1: \(sha1)")
}
if let sha224 = value.hashed(.sha224) {
    print("sha224: \(sha224)")
}
if let sha256 = value.hashed(.sha256) {
    print("sha256: \(sha256)")
}
if let sha384 = value.hashed(.sha384) {
    print("sha384: \(sha384)")
}
if let sha512 = value.hashed(.sha512) {
    print("sha512: \(sha512)")
}

출력 결과는 다음과 같습니다.

md5: c2a9ce57e8df081b4baad80d81868bbb
sha1: 37fb219bf98bee51d2fdc3ba6d866c97f06c8223
sha224: f88e2f20aa89fb4dffb6bdc62d7bd75e1ba02574fae4a437c3bf49c7
sha256: 9da6c02379110815278b615f015f0b254fd3d5a691c9d8abf8141655982c046b
sha384: d9d7fc8aefe7f8f0a969b132a59070836397147338e454acc6e65ca616099d03a61fcf9cc8c4d45a2623145ebd398450
sha512: 349cc35836ba85915ace9d7f895b712fe018452bb4b20ff257257e12adeb1e83ad780c6568a12d03f5b2cb1e3da23b8b7ced9012a188ef3855e0a8f3db211883

SWIFT 3 버전md5 function:

func md5(_ string: String) -> String {

    let context = UnsafeMutablePointer<CC_MD5_CTX>.allocate(capacity: 1)
    var digest = Array<UInt8>(repeating:0, count:Int(CC_MD5_DIGEST_LENGTH))
    CC_MD5_Init(context)
    CC_MD5_Update(context, string, CC_LONG(string.lengthOfBytes(using: String.Encoding.utf8)))
    CC_MD5_Final(&digest, context)
    context.deallocate(capacity: 1)
    var hexString = ""
    for byte in digest {
        hexString += String(format:"%02x", byte)
    }

    return hexString
}

http://iosdeveloperzone.com의 원래 링크

Swift 4.* , Xcode 10 업데이트:

Xcode 10에서는 Bridging-Header를 사용하지 않아도 됩니다.

import CommonCrypto

그런 다음 다음과 같은 방법을 씁니다.

func MD5(_ string: String) -> String? {
        let length = Int(CC_MD5_DIGEST_LENGTH)
        var digest = [UInt8](repeating: 0, count: length)

        if let d = string.data(using: String.Encoding.utf8) {
            _ = d.withUnsafeBytes { (body: UnsafePointer<UInt8>) in
                CC_MD5(body, CC_LONG(d.count), &digest)
            }
        }

        return (0..<length).reduce("") {
            $0 + String(format: "%02x", digest[$1])
        }
    }

사용방법:

MD5("This is my string")

출력:

c2a9ce57e8df081b4baad80d81868bbb

Swift 5.3에서는

import CryptoKit

func md5Hash(_ source: String) -> String {
    return Insecure.MD5.hash(data: source.data(using: .utf8)!).map { String(format: "%02hhx", $0) }.joined()
}

CommonCrypto나 다른 것에 의존하지 않는 순수 Swift 구현을 출시했습니다.MIT 라이선스로 이용할 수 있습니다.

코드는 프로젝트에 드롭할 수 있는 단일 swift 파일로 구성됩니다.원하는 경우 포함된 Xcode 프로젝트를 프레임워크 및 단위 테스트 대상과 함께 사용할 수도 있습니다.

사용법은 간단합니다.

let input = "The quick brown fox jumps over the lazy dog"
let digest = input.utf8.md5
print("md5: \(digest)")

인쇄: 인:md5: 9e107d9d372bb6826bd81d3542a419d6

swift 파일에는 문서 및 기타 예가 포함되어 있습니다.

여기 두 가지 주의사항이 있습니다.

암호 사용은 이 작업에만 너무 많은 오버헤드를 초래합니다.

인정된 답변은 완벽합니다!하지만 Swift 2.2를 사용한 Swift ier 코드 접근 방식을 공유하고자 합니다.

Please bear in mind that you still have to 그래도 해야 한다는 걸 명심하세요.#import <CommonCrypto/CommonCrypto.h>Bridging-Header 파일에서

struct MD5Digester {
    // return MD5 digest of string provided
    static func digest(string: String) -> String? {

        guard let data = string.dataUsingEncoding(NSUTF8StringEncoding) else { return nil }

        var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)

        CC_MD5(data.bytes, CC_LONG(data.length), &digest)

        return (0..<Int(CC_MD5_DIGEST_LENGTH)).reduce("") { $0 + String(format: "%02x", digest[$1]) }
    }
}

String 확장자로 Swift 5에 응답합니다(Invictus Cody의 훌륭한 답변에 근거합니다).

import CommonCrypto

extension String {
    var md5Value: String {
        let length = Int(CC_MD5_DIGEST_LENGTH)
        var digest = [UInt8](repeating: 0, count: length)

        if let d = self.data(using: .utf8) {
            _ = d.withUnsafeBytes { body -> String in
                CC_MD5(body.baseAddress, CC_LONG(d.count), &digest)

                return ""
            }
        }

        return (0 ..< length).reduce("") {
            $0 + String(format: "%02x", digest[$1])
        }
    }
}

사용방법:

print("test".md5Value) /*098f6bcd4621d373cade4e832627b4f6*/

여기 zaph 답변에 기반한 확장자가 있습니다.

extension String{
    var MD5:String {
        get{
            let messageData = self.data(using:.utf8)!
            var digestData = Data(count: Int(CC_MD5_DIGEST_LENGTH))

            _ = digestData.withUnsafeMutableBytes {digestBytes in
                messageData.withUnsafeBytes {messageBytes in
                    CC_MD5(messageBytes, CC_LONG(messageData.count), digestBytes)
                }
            }

            return digestData.map { String(format: "%02hhx", $0) }.joined()
        }
    }
}

Fully compatible with swift 3.0.you still have to Swift 3.0과 완전히 호환됩니다.또,#import <CommonCrypto/CommonCrypto.h>브리징 헤드라인더 파일 하이브리드 파일 하이브리드 일 에 서 in

신속한 프로그래밍에서는 문자열 기능을 만드는 것이 좋기 때문에 사용하기 쉬울 것입니다.여기에서는 위의 솔루션 중 하나를 사용하여 String 확장자를 만듭니다.감사합니다 @wajih

import Foundation
import CommonCrypto

extension String {

func md5() -> String {

    let context = UnsafeMutablePointer<CC_MD5_CTX>.allocate(capacity: 1)
    var digest = Array<UInt8>(repeating:0, count:Int(CC_MD5_DIGEST_LENGTH))
    CC_MD5_Init(context)
    CC_MD5_Update(context, self, CC_LONG(self.lengthOfBytes(using: String.Encoding.utf8)))
    CC_MD5_Final(&digest, context)
    context.deallocate()
    var hexString = ""
    for byte in digest {
        hexString += String(format:"%02x", byte)
    }

    return hexString
}
}

사용.

let md5String = "abc".md5()

Swift 5.3: @Radu Ursache 및 @mluisbrown 응답: String을 통한 단순한 확장

import CryptoKit

extension String {
    func md5() -> String {
        Insecure.MD5.hash(data: self.data(using: .utf8)!).map { String(format: "%02hhx", $0) }.joined()
    }
}

사용방법:

"My awesome String".md5()

// 편집:지금은 매개 변수가 없는 함수보다 계산된 속성을 선호합니다.

import CryptoKit

extension String {
    var md5: String {
       Insecure.MD5.hash(data: self.data(using: .utf8)!).map { String(format: "%02hhx", $0) }.joined()
    }
}

사용방법:

"My awesome String".md5
import CryptoKit
private func MD5Base64(_ string: String) -> String {
    let digest = Insecure.MD5.hash(data: string.data(using: .utf8) ?? Data())
    let digestString = digest.map { String(format: "%02hhx", $0) }.joined()
    return digestString.toBase64()
}

extension String {
    func toBase64() -> String {
        return Data(self.utf8).base64EncodedString()
    }
}

Swift 5를 위한 적절한 메모리 관리 및 비탑재형 솔루션String메서드:

typealias CBridgeCryptoMethodType = (UnsafeRawPointer?,
                                 UInt32,
                                 UnsafeMutablePointer<UInt8>?)
-> UnsafeMutablePointer<UInt8>?

private enum HashType {

    // MARK: - Cases

    case md5
    case sha1
    case sha224
    case sha256
    case sha384
    case sha512
}

extension Data {
    var hexString: String {
        let localHexString = reduce("", { previous, current in
            return previous + String(format: "%02X", current)
        })
        return localHexString
    }
    var md5: Data {
        return hashed(for: .md5)
    }
    var sha1: Data {
        return hashed(for: .sha1)
    }
    var sha224: Data {
        return hashed(for: .sha224)
    }
    var sha256: Data {
        return hashed(for: .sha256)
    }
    var sha384: Data {
        return hashed(for: .sha384)
    }
    var sha512: Data {
        return hashed(for: .sha512)
    }

    private func hashed(for hashType: HashType) -> Data {
        return withUnsafeBytes { (rawBytesPointer: UnsafeRawBufferPointer) -> Data in
            guard let bytes = rawBytesPointer.baseAddress?.assumingMemoryBound(to: Float.self) else {
                return Data()
            }
            let hashMethod: CBridgeCryptoMethodType
            let digestLength: Int
            switch hashType {
            case .md5:
                hashMethod = CC_MD5
                digestLength = Int(CC_MD5_DIGEST_LENGTH)
            case .sha1:
                hashMethod = CC_SHA1
                digestLength = Int(CC_SHA1_DIGEST_LENGTH)
            case .sha224:
                hashMethod = CC_SHA224
                digestLength = Int(CC_SHA224_DIGEST_LENGTH)
            case .sha256:
                hashMethod = CC_SHA256
                digestLength = Int(CC_SHA256_DIGEST_LENGTH)
            case .sha384:
                hashMethod = CC_SHA384
                digestLength = Int(CC_SHA384_DIGEST_LENGTH)
            case .sha512:
                hashMethod = CC_SHA512
                digestLength = Int(CC_SHA512_DIGEST_LENGTH)
            }
            let result = UnsafeMutablePointer<UInt8>.allocate(capacity: digestLength)
            _ = hashMethod(bytes, CC_LONG(count), result)
            let md5Data = Data(bytes: result, count: digestLength)
            result.deallocate()
            return md5Data
        }
    }
}

let str = "The most secure string ever"
print("md5", str.data(using: .utf8)?.md5.hexString)
print("sha1", str.data(using: .utf8)?.sha1.hexString)
print("sha224", str.data(using: .utf8)?.sha224.hexString)
print("sha256", str.data(using: .utf8)?.sha256.hexString)
print("sha384", str.data(using: .utf8)?.sha384.hexString)
print("sha512", str.data(using: .utf8)?.sha512.hexString)

결과:

md5 옵션("671C121427F12FB")BA66CEE71C44CB62C")

sha1 옵션("A6A40B223")AE634CFC8C191DDE024BF0ACA56D7FA)

sha224 옵션("334370E82F5ECF5B2CA0910C6176D94CBA12")FD6F518A7AB8D12ADE")

sha256 옵션("8CF5ED971D6")EE2579B1BDEFD4921415AC03DA45B49B89665B3DF197287EFC89D")

sha384 옵션("04BB3551CBD60035")BA7E0BAA141AEACE1EF5E17317A8FD108DA12A7A8E98C245E14F92CC1A241C732209EAC9D600602E")

sha512 옵션("1D595EAFEB2162672830885D336F75")FD481548AC463BE16A8D98DB33637213F1AEB36FA4977B9C23A82A4FAB8A70C06AFC64C610D3CB1FE77A609DC8EE86AA68")

난 카르타고와 시렙토를 이용해 이 일을 했지

  1. 아직 카르타고를 설치하지 않은 경우 설치

  2. 프로젝트에 암호 설치

  3. '업데이트' 실행

  4. 명령줄에서 실행 중인 경우 swift 파일의 프레임워크에 추가

    #!/usr/bin/env xcrun swift -F Carthage/Build/Mac
    
  5. swift 파일에 Import Crypto를 추가합니다.

  6. 그럼 되는 거야!

    print( "convert this".MD5 )
    

MD5는 해시 알고리즘이므로 대용량 CommonCrypto 라이브러리를 사용할 필요가 없습니다(또한 Apple 리뷰에 의해 거부됩니다).md5 해시 라이브러리를 사용하면 됩니다.

제가 사용하고 있는 라이브러리는 MD5의 완전 신속한 구현인 SwiftHash입니다(http://pajhome.org.uk/crypt/md5/md5.html) 기반).

Cody의 솔루션을 바탕으로 MD5의 결과를 16진수 문자열 또는 Base64 문자열로 사용할 수 있기 때문에 MD5의 결과를 명확히 해야 한다고 생각합니다.

func md5(_ string: String) -> [UInt8] {
    let length = Int(CC_MD5_DIGEST_LENGTH)
    var digest = [UInt8](repeating: 0, count: length)

    if let d = string.data(using: String.Encoding.utf8) {
        _ = d.withUnsafeBytes { (body: UnsafePointer<UInt8>) in
            CC_MD5(body, CC_LONG(d.count), &digest)
        }
    }
    return digest
}

위의 함수는 실제로 a를 반환합니다.[UInt8]이 결과에 따라 16진수, base64 등 임의의 형식의 문자열을 얻을 수 있습니다.

최종 결과로서 16진 스트링이 필요한 경우(질문대로), Cody 솔루션의 나머지 부분을 계속 사용할 수 있습니다.

extension String {
    var md5Hex: String {
        let length = Int(CC_MD5_DIGEST_LENGTH)
        return (0..<length).reduce("") {
            $0 + String(format: "%02x", digest[$1])
        }
    }
}

Base64 문자열이 최종 결과로 필요한 경우

extension String {
    var md5Base64: String {
        let md5edData = Data(bytes: md5(self))
        return md5edData.base64EncodedString()
    }
}

나는 꽤 잘 작동하는 것 같은 이 도서관을 발견했다.

https://github.com/onmyway133/SwiftHash

MD5("string")

my two cents (Data/NSData md5가 필요한 경우, 예를 들어 디스크 또는 network 용 바이너리를 다운로드하거나 읽었을 경우)

('Swift 5 answer as a String extension'(Invictus Cody의 훌륭한 답변에 기초함):

extension Data {
    var md5Value: String {
        let length = Int(CC_MD5_DIGEST_LENGTH)
        var digest = [UInt8](repeating: 0, count: length)

        _ = self.withUnsafeBytes { body -> String in
            CC_MD5(body.baseAddress, CC_LONG(self.count), &digest)
            return ""
        }


        return (0 ..< length).reduce("") {
            $0 + String(format: "%02x", digest[$1])
        }
    }
} 

테스트:

print("test".data.md5Value) /*098f6bcd4621d373cade4e832627b4f6*/

언급URL : https://stackoverflow.com/questions/32163848/how-can-i-convert-a-string-to-an-md5-hash-in-ios-using-swift

반응형