Algoritma MD5 di Objective-C

Jawaban:

219

md5 tersedia di iPhone dan dapat ditambahkan sebagai tambahan untuk ie NSStringdan NSDataseperti di bawah ini.

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

Menambahkan NSData md5 karena saya membutuhkannya sendiri dan menurut saya ini adalah tempat yang baik untuk menyimpan cuplikan kecil ini ...

Metode ini diverifikasi menggunakan vektor uji NIST MD5 di http://www.nsrl.nist.gov/testdata/

epatel
sumber
Apakah ini menarik seluruh file ke dalam memori?
openfrog
Ini bukan tentang file. Jika Anda ingin membuat MD5 dari file dengan metode ini, Anda dapat melakukan NSData * fileContents = [NSData dataWithContentsOfFile: @ "<yourPath>"]; NSString * myHash = [fileContents md5]; Dan ya, ini akan menarik seluruh file ke dalam memori. Jika Anda menemukan solusi yang berfungsi dengan aliran file, silakan posting sebagai jawaban.
Klaas
1
Jika Anda membutuhkan file hash, Anda harus menggunakan CC_MD5_Init, lalu CC_MD5_Update untuk semua data file, dan setelah itu - CC_MD5_Finish.
Nickolay Olshevsky
7
Mengompilasi untuk arsitektur 64 bit, panggilan untuk strlenmenghasilkan peringatan: "Konversi implisit kehilangan presisi integer: 'unsigned long' menjadi 'CC_LONG' (alias 'unsigned int')"
MaxGabriel
55

Anda dapat menggunakan pustaka Crypto Umum bawaan untuk melakukannya. Ingatlah untuk mengimpor:

#import <CommonCrypto/CommonDigest.h>

lalu:

- (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;
}
Bruno Koga
sumber
Saya menerapkan kode di atas tetapi saat menjalankan aplikasi itu macet (CC_MD5 (cStr, strlen (cStr), digest) ----> baris ini melempar pengecualian yang mengatakan EXC_BAD_ACCESS)
Nilesh Kumar
@wimcNilesh periksa selfsebelum mengeksekusi; jika diri tidak ada, itu akan hancur.
brandonscript
4
Jawaban ini jauh lebih bersih untuk dibaca daripada yang lain; satu hal yang dibutuhkan adalah pemeran (int)sebelum strlenmisalnya (int)strlen...
brandonscript
Hay Ini bagus +1 upvote, Dan bisakah Anda memberikan metode Dekripsi md5 sama seperti enkripsi Anda.
Ayaz
@Ayaz MD5 tidak dapat mendekripsi (setidaknya dengan sebuah metode).
albanx
9

Jika kinerja penting, Anda dapat menggunakan versi yang dioptimalkan ini. Ini sekitar 5 kali lebih cepat daripada yang dengan stringWithFormatatau NSMutableString.

Ini adalah kategori 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;
}
Pavel Alexeev
sumber
0

Nah karena orang meminta versi file-stream. Saya telah memodifikasi potongan kecil yang bagus yang dibuat oleh Joel Lopes Da Silva yang bekerja dengan MD5, SHA1 dan SHA512 DAN menggunakan aliran. Ini dibuat untuk iOS tetapi berfungsi hanya dengan sedikit perubahan pada OSX juga (hapus metode ALAssetRepresentation). Itu dapat membuat checksum untuk file yang diberi jalur file atau ALAssets (menggunakan ALAssetRepresentation). Ini memecah data menjadi paket kecil yang membuat dampak memori minimal terlepas dari ukuran file / aset.

Saat ini ada di github di sini: https://github.com/leetal/FileHash

Alexander W.
sumber
Kode yang diterbitkan Joel memiliki kondisi balapan, dan sepertinya kode Anda mungkin mewarisinya. Lihat komentar yang saya terbitkan di postingan Joel. joel.lopes-da-silva.com/2010/09/07/…
xyzzycoder
Terima kasih! Tambal sekarang. Ini tidak pernah menjadi masalah bagi saya karena dalam implementasi asli, saya selalu menjalankannya di utas khusus;)
Alexander W
0

Alasan apa pun untuk tidak menggunakan implementasi Apple: https://developer.apple.com/library/mac/documentation/Security/Conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html#//apple_ref/doc/uid/TP40011172-CH9-SW1

Cari Panduan Layanan Kriptografi di situs pengembang Apple.

vpathak.dll
sumber
Tautan tersebut mencakup Common Crypto yang digunakan sebagian besar jawaban di sini.
zaf
1
Tentu algo itu sama. Tetapi perhatikan bahwa menerapkan algoritme kripto Anda sendiri dapat menimbulkan kekurangan. Dibutuhkan banyak pengerasan untuk membuatnya benar di semua skenario. Jadi menggunakan versi pustaka lebih disukai, dalam kasus umum.
vpathak