dans objective-c, nous pouvons chiffrer une chaîne avec md5 avec les codes suivants
const char *cStr = [someString UTF8String];
unsigned char result[16];
CC_MD5( cStr, strlen(cStr), result );
md5String = [NSString stringWithFormat:
@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
mais maintenant, CC_MD5 ne fonctionne pas dans Swift .. Comment gérer cela.
C'est ce que je suis venu avec. C'est une extension de String . N'oubliez pas d'ajouter #import <CommonCrypto/CommonCrypto.h>
à l'en-tête de pont ObjC-Swift créé par Xcode.
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)
}
}
Voici ma version dans Swift 3.0, je crois que c'est plus sûr et plus rapide que les autres réponses ici.
Un en-tête de pontage avec #import <CommonCrypto/CommonCrypto.h>
est requis.
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])
}
}
J'ai implémenté purement Swift de MD5 dans le cadre de CryptoSwift project.
Je pourrais copier le code ici, mais il utilise des extensions qui font partie de ce projet, ce qui le rend inutile pour une utilisation copier-coller. Cependant, vous pouvez y jeter un coup d'œil et l'utiliser.
BridgingHeader -> Utilisé pour Expose le code Objective-c dans un projet Swift
CommonCrypto -> est le fichier nécessaire pour utiliser md5 hash
Common Crypto étant un fichier Objective-c, vous devez utiliser BridgingHeader pour utiliser la méthode nécessaire au hachage.
(par exemple)
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)
}
}
Comment ajouter Common Crypto à un projet Swift?
Ce link vous apprendra comment (STEP by STEP).
Je recommande d'utiliser Bridging Header
************* Mise à jour 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
}
}
Comment utiliser?
laissez stringConvertedToMD5 = "foo" .toMD5 ()
Besoin d'importer #import <CommonCrypto/CommonCrypto.h>
dans Bridging Header
Je calcule le hachage MD5, mais je n'utilise que les 16 premiers octets.
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
}
si vous voulez calculer MD5 à partir de NSData, jetez un coup d’œil à ceci:
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;
}
pour avoir une idée.
Dans les cas où l'en-tête de pontage n'est pas une option (par exemple, dans un script Shell), vous pouvez utiliser l'outil de ligne de commande /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
Xcode 6 beta 5 utilise maintenant une UnsafeMutablePointer
à la place de UnsafePointer
. La conversion de chaîne nécessite également le libellé de l'argument format:
.
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)
}
}
Voici quelques corrections que j'ai dû apporter à ce code pour le faire fonctionner dans Swift 5
func md5(inString: String) -> String! {
let str = inString.cString(using: String.Encoding.utf8)
let strLen = CUnsignedInt(inString.lengthOfBytes(using: String.Encoding.utf8))
let digestLen = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
CC_MD5(str!, strLen, result)
var hash = NSMutableString()
for i in 0..<digestLen {
hash.appendFormat("%02x", result[i])
}
result.deallocate()
return String(format: hash as String)
}