Подтвердить что ты не робот

Генерировать хэш из UIImage

Я пытаюсь сравнить два UIImages из файловой системы, чтобы убедиться, что они одинаковые. Очевидно, я не могу использовать хэш-метод NSObject, так как это возвращает хэш объекта, а не фактические данные изображения.

Я обнаружил, что код генерирует хеш MD5 из строки, но я не обнаружил, как реализовать его для UIImage.

Как я могу использовать хэширование UIImage? Или мой метод сравнения с изображениями полностью отключен?

4b9b3361

Ответ 1

Я завершил работу с помощью следующего кода для выполнения задачи. Обратите внимание, что для этого требуется импортировать <CommonCrypto/CommonDigest.h>:

unsigned char result[CC_MD5_DIGEST_LENGTH];
NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(inImage)];
CC_MD5([imageData bytes], [imageData length], result);
NSString *imageHash = [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]
                       ];

Ответ 2

Менее оптимальное решение:

[ UIImagePNGRepresentation( uiImage1 ) isEqualToData: 
      UIImagePNGRepresentation( uiImage2 ) ];

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

Ответ 3

UIImage Hashing

Swift-код для хеширования UIImage с алгоритмом SHA256 в swift 4.2. Вы можете использовать другие алгоритмы, которые могут быть быстрее или генерировать меньше дубликатов, но этого достаточно для большинства случаев использования.

Просто yourUIImage.sha256() код где-нибудь в свой проект и используйте его так: yourUIImage.sha256()

extension UIImage{

    public func sha256() -> String{
        if let imageData = cgImage?.dataProvider?.data as? Data {
            return hexStringFromData(input: digest(input: imageData as NSData))
        }
        return ""
    }

    private func digest(input : NSData) -> NSData {
        let digestLength = Int(CC_SHA256_DIGEST_LENGTH)
        var hash = [UInt8](repeating: 0, count: digestLength)
        CC_SHA256(input.bytes, UInt32(input.length), &hash)
        return NSData(bytes: hash, length: digestLength)
    }

    private  func hexStringFromData(input: NSData) -> String {
        var bytes = [UInt8](repeating: 0, count: input.length)
        input.getBytes(&bytes, length: input.length)

        var hexString = ""
        for byte in bytes {
            hexString += String(format:"%02x", UInt8(byte))
        }

        return hexString
    }
}

Соединительный заголовок

Кстати, вам нужен Bridging Header, который импортирует CommonCrypto. Если у вас его нет, выполните следующие действия:

  1. Создать новый файл → Файл заголовка → Сохранить как BridgingHeader
  2. В настройках сборки → заголовок моста Objective-C → добавить ProjectName/BridgingHeader.h
  3. Поместите #import <CommonCrypto/CommonHMAC.h> в свой заголовочный файл

Дублирующая вероятность

Вероятность дублирования низкая, но вы можете сравнительно легко перейти на SHA512, если получили огромные наборы данных:

Дубликат Вероятность о:

enter image description here

Источник: https://crypto.stackexchange.com/questions/24732/probability-of-sha256-collisions-for- sure-amount-of-hashed-values

Ответ 4

более элегантный код ниже

+(NSString *)MD5HexDigest:(NSData *)input {
    unsigned char result[CC_MD5_DIGEST_LENGTH];

    CC_MD5(input.bytes, (unsigned int)input.length, result);
    NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
    for (int i = 0; i<CC_MD5_DIGEST_LENGTH; i++) {
        [ret appendFormat:@"%02x",result[i]];
    }
    return ret;
}