How to calculate the MD5 in Objective-C?
-
1My guess is that you can fairly easily port a C routine that calculates MD5. And they're easy to find. – Artelius Feb 04 '11 at 01:59
5 Answers
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/

- 654
- 8
- 20

- 45,805
- 17
- 110
- 144
-
-
This is not about files. If you want to create a MD5 from a file with these methods, then you can do NSData *fileContents = [NSData dataWithContentsOfFile:@"
"]; NSString *myHash = [fileContents md5]; And yes, this would pull the whole file into memory. If you find a solution that works with file streams, please post it as an answer. – Klaas Aug 07 '13 at 15:44 -
1If you need to hash file, you should use CC_MD5_Init, then CC_MD5_Update for all file data, and after that - CC_MD5_Finish. – Nickolay Olshevsky Aug 12 '13 at 21:09
-
7Compiling for a 64 bit architecture, the call to `strlen` yields the warning: "Implicit conversion loses integer precision: 'unsigned long' to 'CC_LONG' (aka 'unsigned int')" – MaxGabriel Mar 21 '14 at 20:12
-
No visible @interface for 'ViewController' declares the selector 'UTF8String' any suggestions? – nonickname Mar 31 '21 at 10:05
-
@neo999 - Looks like you're trying to call the `UTF8String` method on a `UIViewController` instance. In the code above, @epatel implements an instance method, `md5` in a category on the `NSString` class. So an instance of NSString, let's say `myString` with a value of "Hello, World!" would be called like so: `[myString md5]`, and then the md5 method would return "65a8e27d8879283831b664bd8b7f0ad4". – seeker12 Apr 27 '21 at 23:23
-
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;
}

- 3,864
- 2
- 34
- 45
-
I implemented the above code but while running the application it's crashing(CC_MD5( cStr, strlen(cStr), digest )---->this line is throwing exception saying EXC_BAD_ACCESS) – Nilesh Kumar May 15 '14 at 06:54
-
@wimcNilesh check for `self` before executing; if self is nil, it'll crash. – brandonscript Nov 15 '14 at 07:02
-
4This answer is a lot cleaner to read than the others; one thing it needs is a cast to `(int)` before `strlen` e.g. `(int)strlen`... – brandonscript Nov 15 '14 at 07:02
-
Hay This is nice +1 upvote, And can you please also provide md5 Decryption method same as your's encryption. – Ayaz Nov 24 '14 at 07:13
-
-
Just to point a detail out, but you should be returning [output copy]; , otherwise you're actually returning an NSMutableString. – Goles Mar 06 '17 at 18:13
-
@Ayaz - MD5 is a 128-bit cryptographic hash function by design (Ronald Rivest 1991) but has since been found to be cryptographically broken. However, a cryptographic hash function, known as a "one-way function", is useful precisely because it cannot be "decrypted". It is designed to take an input of arbitrary length, e.g. a text document, and output a fixed-length hash value. So an original input can be hashed with the same function and compared to the hash of an input in question; if the two outputs are exactly the same, the original input has certainly been unmodified. – seeker12 Apr 27 '21 at 23:43
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;
}

- 6,026
- 4
- 43
- 51
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.

- 1,133
- 12
- 12
-
-
1Sure the algo is same. But note that implementing your own crypto algorithm can introduce flaws. It takes a lot of hardening to get it correct in **all** the scenarios. So using the library version is to be preferred, in the common case. – vpathak Mar 16 '15 at 18:00
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

- 1,118
- 1
- 10
- 24
-
The code that Joel published has a race condition, and it looks like yours may inherit it. See the comment that I published on Joel's post. https://www.joel.lopes-da-silva.com/2010/09/07/compute-md5-or-sha-hash-of-large-file-efficiently-on-ios-and-mac-os-x/ – xyzzycoder Oct 10 '14 at 05:47
-
Thanks! Patched it up now. This was never a problem for me since in the original implementation, I always ran it in a dedicated thread ;) – Widerberg Oct 10 '14 at 08:59