Хэш MD5 изображения ALAssetRepresentation не соответствует дублированному хешу изображения ALAssetRepresentation - PullRequest
2 голосов
/ 20 сентября 2011

Я использую следующее для создания объекта NSData из ALAssetRepresentation для экспорта файла изображения, а также для создания хеша md5 из:

- (NSUInteger)getBytes:(uint8_t *)buffer fromOffset:(long long)offset length:(NSUInteger)length error:(NSError **)error;

Когда я повторно добавляю экспортированный файл и выполняю ту же операцию, хэш файла md5 отличается.

Когда я создаю объекты NSData с помощью UIImagePNGRepresentation () и выполняю вышеуказанные операции, хэши md5 совпадают.

Я пытаюсь избежать использования UIImagePNGRepresentation (), так как это значительно дороже того, что я делаю, чем метод getsBytes.

Любые идеи будут оценены!

1 Ответ

3 голосов
/ 21 ноября 2013

Разница в том, что UIImagePNGRepresentation () возвращает только данные изображения и игнорирует заголовки файлов.

Проблема в том, что вы, вероятно, начинаете со смещения 0. Это будет читать заголовки файлов, которые испортят ваше хеширование (так как они могут быть одинаковыми изображениями, но имеют другую дату создания).

Вместо этого, вот пример чтения 1K из середины файла. Для изображения это будет считывать только около 340 пикселей, поэтому вы можете увеличить размер сравнения примерно до 20 КБ или более, если сравниваете изображения, например, для дубликатов.

Код будет таким:

    #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 секунды, где оно уменьшилось до примерно 0,00008 секунд при сравнении всего 1 КБ каждого изображения, считываемого из середины файла.

...