違いは、UIImagePNGRepresentation() が画像データのみを返し、ファイル ヘッダーを無視することです。
問題は、おそらくオフセット 0 から開始していることです。これにより、ファイル ヘッダーが読み取られ、ハッシュが台無しになります (同じ画像である可能性がありますが、作成日が異なるため)。
代わりに、ファイルの途中から 1K を読み取る例を次に示します。画像の場合、これは約 340 ピクセルしか読み取らないため、たとえば画像の重複を比較する場合は、比較サイズを約 20K 以上に増やすことができます。
コードは次のようになります。
#import <CommonCrypto/CommonCrypto.h>
#define HASH_DATA_SIZE 1024 // Read 1K of data to be hashed
...
ALAssetRepresentation *rep = [anAsset defaultRepresentation];
Byte *buffer = (Byte *) malloc(rep.size);
long long offset = rep.size / 2; // begin from the middle of the file
NSUInteger buffered = [rep getBytes:buffer fromOffset:offset length:HASH_DATA_SIZE error:nil];
if (buffered > 0)
{
NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES]
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5([data bytes], [data length], result);
NSString *hash = [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]
];
NSLog(@"Hash for image is %@", hash);
}
約4000枚の写真でこれを試しました。UIImagePNGRepresentation() を使用した場合の画像全体の平均ハッシュ時間は 0.008 秒でしたが、ファイルの中央から読み取った各画像の 1K のみを比較すると、約 0.00008 秒に低下しました。