Cómo utilizar el método CC_MD5 en lenguaje rápido.
swift (9)
Así que aquí está la solución y sé que ahorrará tiempo al 100%.
BridgingHeader -> Se utiliza para exponer el código de Objective-c a un proyecto Swift
CommonCrypto -> es el archivo necesario para usar el hash md5
Ya que Common Crypto es un archivo Objective-c, necesita usar BridgingHeader para usar el método necesario para el hashing
(p.ej)
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)
}
}
¿Cómo agregar Common Crypto en un proyecto Swift?
Este link te enseñará cómo (PASO A PASO).
Recomiendo usar Bridging Header
************* Actualizado 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
}
}
¿Cómo utilizar?
deje stringConvertedToMD5 = "foo" .toMD5 ()
en object-c, podemos cifrar una cadena con md5 mediante los siguientes códigos
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]
];
pero ahora CC_MD5 no funciona en swift. Cómo lidiar con esto.
Aquí está mi versión en Swift 3.0, creo que es más segura y más rápida que las otras respuestas aquí.
Se requiere un encabezado puente con #import <CommonCrypto/CommonCrypto.h>
.
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])
}
}
Aquí hay algunas correcciones que tuve que hacer con este código para que funcione en 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)
}
Esto es lo que se me ocurrió. Es una extensión de String. No se olvide de agregar #import <CommonCrypto/CommonCrypto.h>
al encabezado de puente ObjC-Swift que crea 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)
}
}
Hice la implementación Swift pura de MD5 como parte del proyecto CryptoSwift .
Podría copiar el código aquí, pero utiliza extensiones que forman parte de este proyecto, por lo que puede ser inútil para copiar y pegar el uso. Sin embargo puedes echar un vistazo allí y usarlo.
Incluso si desea calcular MD5 a partir de NSData, eche un vistazo a esto:
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;
}
para tener idea
Necesita importar #import <CommonCrypto/CommonCrypto.h>
en el encabezado de #import <CommonCrypto/CommonCrypto.h>
Estoy calculando el hash MD5, pero usando solo los primeros 16 bytes que estoy usando
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
}
Para los casos en que un encabezado puente no es una opción (por ejemplo, en un script de shell), puede usar la herramienta de línea de comandos /sbin/md5
través de 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())
}
Uso:
let md5 = md5hash("hello world")
// 5eb63bbbe01eeed093cb22bb8f5acdc3
Xcode 6 beta 5 ahora usa un UnsafeMutablePointer
en lugar de un UnsafePointer
. La conversión de cadenas también requiere el format:
etiqueta de argumento.
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)
}
}