2015-05-17 9 views
5

Sto costruendo un'applicazione per social media e vorrei qualche aiuto per codificare una stringa di password per SHA512 in Swift. Ho trovato la libreria CryptoSwift su GitHub, ma ho difficoltà a caricarlo nel mio progetto Swift e collegarlo ai miei file di progetto. Qualcuno sa come realizzare questo relativamente facilmente? Grazie in anticipo, KyleCome hash una stringa su SHA512 in Swift?

+1

I beliebe CryptoSwift è il modo semplice :) – gutenmorgenuhu

+2

Quali problemi hai esattamente con l'utilizzo di CryptoSwift? - Non hai necessariamente bisogno di un framework di terze parti, puoi anche utilizzare il CommonCrypto di Apple con i wrapper Swift sottili. Esempi: http://stackoverflow.com/questions/25023376/how-can-i-hash-a-nsstring-to-sha512 (la tua domanda :), http://stackoverflow.com/questions/6228092/how- can-i-compute-a-sha-2-ideally-sha-256-or-sha-512-hash-in-ios, http://stackoverflow.com/questions/25761344/how-to-crypt-string- to-sha1-with-swift, http://stackoverflow.com/questions/25388747/sha256-in-swift. –

+0

@ Martinin Grazie per la condivisione! Questa risposta mi ha davvero aiutato! Questo è l'articolo che ha risposto alla mia domanda (http: // StackOverflow.com/domande/25761344/how-to-crypt-string-to-SHA1-con-veloce). Tutto quello che dovevo fare era cambiare SHA1 in SHA512. – TechnologyGuy

risposta

2

Swift 3

func sha512() -> String { 
    let data = self.data(using: .utf8)! 
    var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH)) 
    data.withUnsafeBytes({ 
     _ = CC_SHA512($0, CC_LONG(data.count), &digest) 
    }) 

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

Swift 2,3

func sha512() -> String { 
    let data = self.dataUsingEncoding(NSUTF8StringEncoding)! 
    var digest = [UInt8](count:Int(CC_SHA512_DIGEST_LENGTH), repeatedValue: 0) 
    CC_SHA512(data.bytes, CC_LONG(data.length), &digest) 
    let hexBytes = digest.map { String(format: "%02hhx", $0) } 

    return hexBytes.joinWithSeparator("") 
} 
7

Soluzione Swift 3:

extension String { 

    func sha512() -> String { 
     let data = self.data(using: .utf8)! 
     var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH)) 
     data.withUnsafeBytes({ 
      _ = CC_SHA512($0, CC_LONG(data.count), &digest) 
     }) 
     return digest.map({ String(format: "%02hhx", $0) }).joined(separator: "") 
    } 

} 
+0

Chiedendosi come 'self.data (using: .utf8)' potrebbe mai fallire dato che 'self' deve essere una' String' valida. – zaph

+0

Sì, hai ragione. Le stringhe rapide sono sempre stringhe unicode, quindi 'self.data (using: .utf8)' non può mai fallire. Ho adattato la mia risposta di conseguenza. – sundance

+0

In un parco giochi, cosa devo importare per ottenere l'accesso alle funzioni 'CC_'? La Fondazione non è abbastanza – Jeff

1

È necessario importare la libreria C CommonCrypto. Non puoi semplicemente importare CommonCrypto nel tuo file swift poiché non è un modulo standalone.

Se si dispone di un file di intestazione del bridging, si è fortunati! Basta aggiungere questo al file

#import <CommonCrypto/CommonCrypto.h> 

There are some articles about different ways to do that.

Quindi è possibile utilizzare questo pezzo di codice per avere sha512 a disposizione per qualsiasi stringa di vostra scelta:

extension String { 

    public var sha512: String { 
     let data = self.data(using: .utf8) ?? Data() 
     var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH)) 
     data.withUnsafeBytes({ 
      _ = CC_SHA512($0, CC_LONG(data.count), &digest) 
     }) 
     return digest.map({ String(format: "%02hhx", $0) }).joined(separator: "") 
    } 
} 
2

trovo tutta la risposta ok, ma se dovessimo avere una vera soluzione universale, penso che dovremmo aumentarlo di livello.

CC_LONG è solo un UInt32 e non supporterà strutture di dati veramente grandi.

Questa è la mia soluzione in Swift 3:

Prima creiamo un fondamento:

struct Sha512 { 
    let context = UnsafeMutablePointer<CC_SHA512_CTX>.allocate(capacity:1) 

    init() { 
     CC_SHA512_Init(context) 
    } 

    func update(data: Data) { 
     data.withUnsafeBytes { (bytes: UnsafePointer<Int8>) -> Void in 
      let end = bytes.advanced(by: data.count) 
      for f in sequence(first: bytes, next: { $0.advanced(by: Int(CC_LONG.max)) }).prefix(while: { (current) -> Bool in current < end}) { 
       _ = CC_SHA512_Update(context, f, CC_LONG(Swift.min(f.distance(to: end), Int(CC_LONG.max)))) 
      } 
     } 
    } 

    func final() -> Data { 
     var digest = [UInt8](repeating: 0, count:Int(CC_SHA512_DIGEST_LENGTH)) 
     CC_SHA512_Final(&digest, context) 

     return Data(bytes: digest) 
    } 
} 

Per comodità facciamo un'estensione per Data:

extension Data { 
    func sha512() -> Data { 
     let s = Sha512() 
     s.update(data: self) 
     return s.final() 
    } 
} 

e ultimo un estensione per String:

Questa soluzione può essere utilizzata per Sha256, MD5 ecc. Per ottenere una buona soluzione universale con CommonCrypto di Apple.