I was searching for a way to get an MD5 or SHA1 checksum of a file in Objective-C for an iOS app. I found lots of solutions for getting the checksum of a string, but nothing for files. The solution was pretty simple, but I had to piece together information from a few sources to get it done. I’m surprised that this isn’t common. Well, here it is.
This is the code. Since this ought to be useful, I’ve implemented it as a class. First, the header file (AiChecksum.h).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #import <Foundation/Foundation.h> #include <CommonCrypto/CommonDigest.h> @interface AiChecksum : NSObject { } /** * Get the md5 hash of a file * * @returns NSString * @since 20140120 * @author costmo * @param path Full path to the file */ +(NSString *)md5HashOfPath:(NSString *)path; /** * Get the sha1 hash of a file * * @returns NSString * @since 20140120 * @author costmo * @param path Full path to the file */ +(NSString *)shaHashOfPath:(NSString *)path; |
And now the implementation (AiChecksum.m).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #import "AiChecksum.h" @implementation AiChecksum +(NSString *)md5HashOfPath:(NSString *)path { NSFileManager *fileManager = [NSFileManager defaultManager]; // Make sure the file exists if( [fileManager fileExistsAtPath:path isDirectory:nil] ) { NSData *data = [NSData dataWithContentsOfFile:path]; unsigned char digest[CC_MD5_DIGEST_LENGTH]; CC_MD5( data.bytes, (CC_LONG)data.length, digest ); 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; } else { return @""; } } +(NSString *)shaHashOfPath:(NSString *)path { NSFileManager *fileManager = [NSFileManager defaultManager]; // Make sure the file exists if( [fileManager fileExistsAtPath:path isDirectory:nil] ) { NSData *data = [NSData dataWithContentsOfFile:path]; unsigned char digest[CC_SHA1_DIGEST_LENGTH]; CC_SHA1( data.bytes, (CC_LONG)data.length, digest ); NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; for( int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++ ) { [output appendFormat:@"%02x", digest[i]]; } return output; } else { return @""; } } |
Getting a checksum is simple enough:
1 2 3 4 5 6 7 8 | #import "AiChecksum.h" NSString *fullPath = @""; // do whatever you need to get the full path to your file NSString *md5 = [AiChecksum md5HashOfPath:fullPath]; NSString *sha1 = [AiChecksum shaHashOfPath:fullPath]; NSLog( @"MD5: %@", md5 ); NSLog( @"SHA1: %@", sha1 ); |
That’s all there is to it. Maybe it’ll be useful to someone other than me.