How to use CC_MD5 method in swift language

后端 未结 9 2109
南旧
南旧 2020-12-01 02:52

in Objective-c, we can hash a string like this:

const char *cStr = [someString UTF8String];
unsigned char result[16];
CC_MD5( cStr, strlen(cStr), result );
m         


        
相关标签:
9条回答
  • 2020-12-01 03:08

    So here is the Solution and I know It will save your time 100%

    BridgingHeader - > Used to Expose Objective-c code to a Swift Project

    CommonCrypto - > is the file needed to use md5 hash

    Since Common Crypto is a Objective-c file, you need to use BridgingHeader to use method needed for hashing


    (e.g)

    extension String {
    func md5() -> String! {
        let str = self.cStringUsingEncoding(NSUTF8StringEncoding)
        let strLen = CUnsignedInt(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
        CC_MD5(str!, strLen, result)
        var hash = NSMutableString()
        for i in 0..<digestLen {
            hash.appendFormat("%02x", result[i])
        }
        result.destroy()
        return String(format: hash as String)
    }
    

    }

    How to add Common Crypto into a Swift Project??

    This link will teach you how (STEP by STEP).

    I recommend using Bridging Header

    *************Updated Swift 3****************

    extension String {
    func toMD5()  -> String {
    
            if let messageData = self.data(using:String.Encoding.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.hexString()
            }
    
            return self
        }
    }
    
    
    extension Data {
    
        func hexString() -> String {
            let string = self.map{ String($0, radix:16) }.joined()
            return string
        }
    
    }
    

    How to use?

    let stringConvertedToMD5 = "foo".toMD5()

    0 讨论(0)
  • 2020-12-01 03:13

    For cases where a bridging header isn't an option (eg, in a shell script), you can use the command line tool /sbin/md5 via NSTask:

    import Foundation
    
    func md5hash(string: String) -> String
    {
      let t = NSTask()
      t.launchPath = "/sbin/md5"
      t.arguments = ["-q", "-s", string]
      t.standardOutput = NSPipe()
    
      t.launch()
    
      let outData = t.standardOutput.fileHandleForReading.readDataToEndOfFile()
      var outBytes = [UInt8](count:outData.length, repeatedValue:0)
      outData.getBytes(&outBytes, length: outData.length)
    
      var outString = String(bytes: outBytes, encoding: NSASCIIStringEncoding)
    
      assert(outString != nil, "failed to md5 input string")
    
      return outString!.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet())
    }
    

    Usage:

    let md5 = md5hash("hello world")
    
    // 5eb63bbbe01eeed093cb22bb8f5acdc3
    
    0 讨论(0)
  • 2020-12-01 03:17

    Need import #import <CommonCrypto/CommonCrypto.h> into Bridging Header

    I am calculating MD5 hash, but using only the first 16 byte I am using

    class func hash(data: NSData) -> String {
    
        let data2 = NSMutableData(length: Int(CC_MD5_DIGEST_LENGTH))!
        CC_MD5(data.bytes, CC_LONG(data.length), UnsafeMutablePointer<UInt8>(data2.mutableBytes))
        let data3 =  UnsafePointer<CUnsignedChar>(data2.bytes)
    
        var hash = ""
        for (var i = 0; i < 16; ++i) {
    
            hash +=  String(format: "%02X", data3[i])
        }
    
        return hash
    }
    
    0 讨论(0)
  • 2020-12-01 03:20

    Here's my version in Swift 3.0, I believe it to be safer and faster than the other answers here.

    A bridging header with #import <CommonCrypto/CommonCrypto.h> is required.

    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])
        }
    }
    
    0 讨论(0)
  • 2020-12-01 03:21

    This is what I came up with. It's an extension to String. Don't forget to add #import <CommonCrypto/CommonCrypto.h> to the ObjC-Swift bridging header that Xcode creates.

    extension String  {
        var md5: String! {
            let str = self.cStringUsingEncoding(NSUTF8StringEncoding)
            let strLen = CC_LONG(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
            let digestLen = Int(CC_MD5_DIGEST_LENGTH)
            let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
    
            CC_MD5(str!, strLen, result)
    
            let hash = NSMutableString()
            for i in 0..<digestLen {
                hash.appendFormat("%02x", result[i])
            }
    
            result.dealloc(digestLen)
    
            return String(format: hash as String)
        }
     }
    
    0 讨论(0)
  • 2020-12-01 03:23

    evntually if you want calculate MD5 out of NSData, take a look at this:

    func md5() -> NSData {
        var ctx = UnsafePointer<CC_MD5_CTX>.alloc(sizeof(CC_MD5_CTX))
        CC_MD5_Init(ctx);
    
        CC_MD5_Update(ctx, self.bytes, UInt32(self.length));
        let length = Int(CC_MD5_DIGEST_LENGTH) * sizeof(Byte)
        var output = UnsafePointer<Byte>.alloc(length)
        CC_MD5_Final(output, ctx);
    
        let outData = NSData(bytes: output, length: Int(CC_MD5_DIGEST_LENGTH))
        output.destroy()
        ctx.destroy()
    
        //withUnsafePointer
        return outData;
    }
    

    to get idea.

    0 讨论(0)
提交回复
热议问题