Biranchi
Biranchi

Reputation: 16317

MD5 algorithm in Objective-C

How to calculate the MD5 in Objective-C?

Upvotes: 134

Views: 67155

Answers (5)

epatel
epatel

Reputation: 46051

md5 is available on the iPhone and can be added as an addition for ie NSString and NSData like below.

MyAdditions.h

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

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

MyAdditions.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

Added NSData md5 because I needed it myself and thought this is a good place to save this little snippet...

These methods are verified using the NIST MD5 test vectors in http://www.nsrl.nist.gov/testdata/

Upvotes: 220

vpathak
vpathak

Reputation: 1163

Any reason not to use the Apple implementation: https://developer.apple.com/library/mac/documentation/Security/Conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html#//apple_ref/doc/uid/TP40011172-CH9-SW1

Search for Cryptographic Services Guide on Apple developer site.

Upvotes: 1

Pavel Alexeev
Pavel Alexeev

Reputation: 6081

If performance is important, you can use this optimized version. It is about 5 times faster than the ones with stringWithFormat or NSMutableString.

This is a category of 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;
}

Upvotes: 9

Widerberg
Widerberg

Reputation: 1138

Well since people asked for a file-stream version. I have modified a nice little snippet made by Joel Lopes Da Silva that works with MD5, SHA1 and SHA512 AND it is using streams. Its made for iOS but works with just minimal changes on OSX aswell (remove the ALAssetRepresentation method). It can make checksums for files given a filepath or ALAssets (using ALAssetRepresentation). It's chunking data into small packages making memory impact minimal regardless of the filesize/asset size.

It's currently located on github here: https://github.com/leetal/FileHash

Upvotes: 0

Bruno Koga
Bruno Koga

Reputation: 3874

You can use the built-in Common Crypto library to do so. Remember to import:

#import <CommonCrypto/CommonDigest.h>

and then:

- (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;
}

Upvotes: 55

Related Questions