2017-03-21 1 views
3

J'ai un certain nombre de fichiers qui vont vivre sur un serveur. Les utilisateurs ont la possibilité de créer ces types de fichiers (plistes) sur l'appareil qui seront ensuite téléchargés sur ledit serveur (CloudKit). Je voudrais les unique par le contenu (la méthodologie unique devrait être résiliente aux variations dans la date de création). Ma compréhension est que je devrais hacher ces fichiers afin d'obtenir des noms de fichiers uniques pour eux. Mes questions sont:Comment puis-je hacher un fichier sur iOS en utilisant swift 3?

  1. Est-ce que je comprends bien que ce que je veux est une fonction de hachage?
  2. Quelle fonction dois-je utiliser (à partir de CommonCrypto).
  3. Qu'est-ce que j'ai besoin d'un condensé?
  4. Comment ferais-je cela dans le code? (Je suppose que ceci devrait être haché sur une instance de NSData?). Ma compréhension de googling autour est que j'ai besoin d'un en-tête de pontage mais au-delà que l'utilisation de CommonCrypto me déroute. S'il y a une façon plus simple d'utiliser des API de première partie (Apple), je suis tout ouïe (je veux éviter d'utiliser autant que possible le code d'un tiers).

Merci beaucoup!

+0

Différentes méthodes de hachage ici: http://stackoverflow.com/questions/25388747/sha256-in-swift. –

+0

Grand avertissement. Les fonctions de hachage ne génèrent pas d'identifiants uniques. La collision est possible et vous devriez y faire face. – Sulthan

+0

@Sulthan Bien que cela soit vrai, les hachages cryptographiques sont utilisés en toute sécurité pour identifier les fichiers, voir Git. – zaph

Répondre

5

Créez un hachage cryptographique de chaque fichier et vous pouvez l'utiliser pour les comparaisons d'unicité. SHA-256 est une fonction de hachage actuelle et sur iOS avec Common Crypto est assez rapide, sur un iPhone 6S SHA256 traitera environ 1 Go/seconde moins le temps d'E/S. Si vous avez besoin de moins d'octets, tronquez simplement le hachage.

Un exemple en utilisant Crypto commun (swift3)

pour le hachage d'une chaîne:

func sha256(string: String) -> Data { 
    let messageData = string.data(using:String.Encoding.utf8)! 
    var digestData = Data(count: Int(CC_SHA256_DIGEST_LENGTH)) 

    _ = digestData.withUnsafeMutableBytes {digestBytes in 
     messageData.withUnsafeBytes {messageBytes in 
      CC_SHA256(messageBytes, CC_LONG(messageData.count), digestBytes) 
     } 
    } 
    return digestData 
} 
let testString = "testString" 
let testHash = sha256(string:testString) 
print("testHash: \(testHash.map { String(format: "%02hhx", $0) }.joined())") 

let testHashBase64 = testHash.base64EncodedString() 
print("testHashBase64: \(testHashBase64)") 

sortie:
testHash: 4acf0b39d9c4766709a3689f553ac01ab550545ffa4544dfc0b2cea82fba02a3
testHashBase64: Ss8LOdnEdmcJo2ifVTrAGrVQVF/6RUTfwLLOqC + 6AqM =

Note: Ajouter à votre Bridging tête:

#import <CommonCrypto/CommonCrypto.h> 

Pour les données hachant:

func sha256(data: Data) -> Data { 
    var digestData = Data(count: Int(CC_SHA256_DIGEST_LENGTH)) 

    _ = digestData.withUnsafeMutableBytes {digestBytes in 
     data.withUnsafeBytes {messageBytes in 
      CC_SHA256(messageBytes, CC_LONG(data.count), digestBytes) 
     } 
    } 
    return digestData 
} 

let testData: Data = "testString".data(using: .utf8)! 
print("testData: \(testData.map { String(format: "%02hhx", $0) }.joined())") 
let testHash = sha256(data:testData) 
print("testHash: \(testHash.map { String(format: "%02hhx", $0) }.joined())") 

Sortie:
TestData: 74657374537472696e67
testHash: 4acf0b39d9c4766709a3689f553ac01ab550545ffa4544dfc0b2cea82fba02a3

Voir aussi Martin lien.

+0

Merci pour l'éclairage réponse rapide! Ma lecture de votre code est que la fonction hache une chaîne, comment est-ce que je pourrais hacher le plist (je suppose sur un objet de données)? Aussi, votre appel à base64EncodedString est-il juste un exemple de troncature? (Désolé je n'ai aucune idée de la cryptographie ...) –

+0

La conversion en UTF-8 * ne peut pas * échouer - avons-nous déjà eu cette discussion? –

+0

@ Martin, ah oui, je copiais mon ancien code, corrigeant. Doublement embarrassant depuis que j'ai corrigé une autre personne. – zaph