134 votes

Algorithme MD5 en Objective-C

Comment calculer le MD5 en Objective-C ?

1 votes

Je pense que vous pouvez assez facilement porter une routine C qui calcule le MD5. Et ils sont faciles à trouver.

219voto

epatel Points 32451

Md5 est disponible sur l'iPhone et peut être ajouté comme un complément pour ie NSString y NSData comme ci-dessous.

MesAdditions.h

@interface NSString (MyAdditions)
- (NSString *)md5;
@end

@interface NSData (MyAdditions)
- (NSString*)md5;
@end

MesAdditions.m

#import "MyAdditions.h"
#import <CommonCrypto/CommonDigest.h> // Need to import for CC_MD5 access

@implementation NSString (MyAdditions)
- (NSString *)md5
{
    const char *cStr = [self UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5( cStr, (int)strlen(cStr), result ); // This is the md5 call
    return [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]
        ];  
}
@end

@implementation NSData (MyAdditions)
- (NSString*)md5
{
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5( self.bytes, (int)self.length, result ); // This is the md5 call
    return [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]
        ];  
}
@end

EDIT

J'ai ajouté NSData md5 parce que j'en ai eu besoin moi-même et que j'ai pensé que c'était un bon endroit pour sauvegarder ce petit bout...

Ces méthodes sont vérifiées à l'aide des vecteurs de test MD5 du NIST en http://www.nsrl.nist.gov/testdata/

0 votes

Est-ce que cela met tout le fichier en mémoire ?

0 votes

Il ne s'agit pas de fichiers. Si vous voulez créer un MD5 à partir d'un fichier à l'aide de ces méthodes, vous pouvez faire ce qui suit : NSData *fileContents = [NSData dataWithContentsOfFile:@"<yourPath>"] ; NSString *myHash = [fileContents md5] ; Et oui, cela mettrait tout le fichier en mémoire. Si vous trouvez une solution qui fonctionne avec les flux de fichiers, veuillez la poster comme réponse.

1 votes

Si vous devez hacher un fichier, vous devez utiliser CC_MD5_Init, puis CC_MD5_Update pour toutes les données du fichier, et enfin CC_MD5_Finish.

55voto

Bruno Koga Points 2267

Vous pouvez utiliser la bibliothèque Common Crypto intégrée pour le faire. N'oubliez pas d'importer :

#import <CommonCrypto/CommonDigest.h>

et ensuite :

- (NSString *) md5:(NSString *) input
{
    const char *cStr = [input UTF8String];
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    CC_MD5( cStr, strlen(cStr), digest ); // This is the md5 call

    NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];

    for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
    [output appendFormat:@"%02x", digest[i]];

    return  output;
}

0 votes

J'ai implémenté le code ci-dessus mais lors de l'exécution de l'application, il y a un crash (CC_MD5( cStr, strlen(cStr), digest )---->cette ligne lève une exception disant EXC_BAD_ACCESS)

0 votes

@wimcNilesh vérifier pour self avant de l'exécuter ; si self est nil, il se plantera.

4 votes

Cette réponse est beaucoup plus facile à lire que les autres ; il lui manque un cast vers (int) avant strlen par exemple (int)strlen ...

9voto

Pavel Alexeev Points 1680

Si les performances sont importantes, vous pouvez utiliser cette version optimisée. Elle est environ 5 fois plus rapide que les versions avec stringWithFormat o NSMutableString .

Il s'agit d'une catégorie de NSString.

- (NSString *)md5
{
    const char* cStr = [self UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, strlen(cStr), result);

    static const char HexEncodeChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    char *resultData = malloc(CC_MD5_DIGEST_LENGTH * 2 + 1);

    for (uint index = 0; index < CC_MD5_DIGEST_LENGTH; index++) {
        resultData[index * 2] = HexEncodeChars[(result[index] >> 4)];
        resultData[index * 2 + 1] = HexEncodeChars[(result[index] % 0x10)];
    }
    resultData[CC_MD5_DIGEST_LENGTH * 2] = 0;

    NSString *resultString = [NSString stringWithCString:resultData encoding:NSASCIIStringEncoding];
    free(resultData);

    return resultString;
}

1voto

vpathak Points 158

Toute raison de ne pas utiliser l'implémentation Apple : https://developer.apple.com/library/mac/documentation/Security/Conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html#//apple_ref/doc/uid/TP40011172-CH9-SW1

Recherchez le Guide des services cryptographiques sur le site des développeurs Apple.

0voto

Alexander W Points 264

Eh bien, puisque les gens ont demandé une version pour les flux de fichiers. J'ai modifié un joli petit snippet fait par Joel Lopes Da Silva qui fonctionne avec MD5, SHA1 et SHA512 ET qui utilise des flux. Il est conçu pour iOS mais fonctionne également sous OSX avec des modifications minimes (suppression de la méthode ALAssetRepresentation). Il peut faire des sommes de contrôle pour des fichiers donnés par un chemin de fichier ou des ALAssets (en utilisant ALAssetRepresentation). Il découpe les données en petits paquets, ce qui minimise l'impact sur la mémoire, quelle que soit la taille du fichier ou de l'ensemble.

Il est actuellement situé sur github ici : https://github.com/leetal/FileHash

0 votes

Le code que Joel a publié a une condition de course, et il semble que le vôtre puisse en hériter. Voir le commentaire que j'ai publié sur le post de Joel. joel.lopes-da-silva.com/2010/09/07/

0 votes

Merci ! Je l'ai corrigé maintenant. Cela n'a jamais été un problème pour moi puisque dans l'implémentation originale, je l'ai toujours exécuté dans un fil dédié ;)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X