Как конвертировать строку в MD5 хэш с помощью ios swift
Я хочу преобразовать пользовательский ввод или принять любую строку, такую как" abc", в хэш MD5. Я хочу сделать это в ios swift. Я сослался на приведенные ниже ссылки, но решения не работают для меня, или Я смущен, чтобы реализовать его должным образом, поскольку я новичок в программировании swift. Может ли кто-нибудь помочь мне с четкими шагами для достижения этого. Заранее спасибо!
импорт CommonCrypto в Swift framework
Как использовать метод CC_MD5 в swift язык.
http://iosdeveloperzone.com/2014/10/03/using-commoncrypto-in-swift/
чтобы быть более ясным, я хочу добиться этого в Swift, как то, что мы делаем в PHP.
$str = "Hello";
echo md5($str);
выход: 8b1a9953c4611296a827abf8c47804d7
9 ответов:
есть два шага:
1. Создайте данные md5 из строки
2. Скрытие данных md5 в шестнадцатеричную строку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", ) }.joined() print("md5Hex: \(md5Hex)") let md5Base64 = md5Data.base64EncodedString() print("md5Base64: \(md5Base64)")выход:
md5Hex: 8b1a9953c4611296a827abf8c47804d7
md5Base64: ixqZU8RhEpaoJ6v4xHgE1w==Примечания:
#import <CommonCrypto/CommonCrypto.h>должен быть добавлен в файл заголовка мостакак создать Мостовой заголовок см. это так ответ.
в целом MD5 не следует использовать для новой работы, SHA256 является текущей передовой практикой.
пример из раздела устаревшей документации:
MD2, MD4, MD5, SHA1, SHA224, SHA256, SHA384, SHA512 (Swift 3+)
эти функции будут хэшировать либо строку, либо ввод данных с помощью одного из восьми криптографических алгоритмов хэширования.
параметр name указывает имя хэш-функции в виде строки
Поддерживаемые функции, являются MD2, алгоритмов MD4, MD5 и алгоритма SHA1, SHA224, SHA256 и, значения sha384 и SHA512 один В этом примере требуется Common Crypto
Необходимо иметь заголовок моста к проекту:#import <CommonCrypto/CommonCrypto.h>
Добавьте безопасность.рамки для проекта.
эта функция принимает хэш-имя и строку для хэширования и возвращает данные:
name: A name of a hash function as a String string: The String to be hashed returns: the hashed result as Datafunc 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>
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
отпустил чистая быстрая реализация это не зависит от CommonCrypto или чего-либо еще. Он доступен по лицензии 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 содержит документация и примеры.
здесь всего две заметки:
используя крипто слишком много накладных расходов для достижения всего этого.
The принято отвечать идеально! Тем не менее, я просто хотел поделиться Свифтier кодовый подход с использованием Swift 2.2.
пожалуйста, имейте в виду, что вы все еще должны
#import <CommonCrypto/CommonCrypto.h>в своем Преодоление-Заголовка filestruct 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("") { + String(format: "%02x", digest[]) } } }
вот расширение, основанное на zaph answer
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", ) }.joined() } } }полностью совместим с swift 3.0.вы все еще должны
#import <CommonCrypto/CommonCrypto.h>в вашем файле заголовка моста
после прочтения других ответов здесь (и необходимости поддерживать другие типы хэшей) я написал расширение строки, которое обрабатывает несколько типов хэшей и типов вывода.
Примечание: CommonCrypto входит в Xcode 10, так что вы можете просто
import CommonCryptoбез необходимости возиться с заголовком моста, если у вас установлена последняя версия Xcode... В противном случае необходим мостовой заголовок.SWIFT 4+
Строка+Крипто.Свифт
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) }Данные+Крипто.Свифт
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", ) }.joined() case .base64: return digest.base64EncodedString() } } }Edit: поскольку хэш на самом деле происходит с данными, я разделил алгоритм хэширования на расширение данных. Это позволяет использовать тот же алгоритм для операций хэширования 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
я использовал Карфаген и Cyrpto, чтобы сделать это.
выполнить 'cartage update'
Если вы работаете из командной строки добавить в рамках в swift файл
#!/usr/bin/env xcrun swift -F Carthage/Build/Macдобавить импорт крипто к вашему swift файл.
тогда это просто работает!
print( "convert this".MD5 )
MD5-это алгоритм хеширования, для этого не нужно использовать громоздкую библиотеку CommonCrypto (и получить отклонение от Apple review), просто используйте любую библиотеку хеширования md5.
одна из таких библиотек я использую SwiftHash, чистая быстрая реализация MD5 (на основе http://pajhome.org.uk/crypt/md5/md5.html)
Я нашел эту библиотеку, которая, кажется, работает довольно хорошо.
https://github.com/onmyway133/SwiftHash
MD5("string")
Comments