Algoritmo MD5 in Objective-C


Risposte:


219

md5 è disponibile su iPhone e può essere aggiunto come aggiunta per ie NSStringe NSDatacome di seguito.

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

MODIFICARE

Aggiunto NSData md5 perché ne avevo bisogno me stesso e ho pensato che questo fosse un buon posto per salvare questo piccolo frammento ...

Questi metodi sono verificati utilizzando i vettori di test NIST MD5 in http://www.nsrl.nist.gov/testdata/


Questo estrae l'intero file in memoria?
openfrog,

Non si tratta di file. Se si desidera creare un MD5 da un file con questi metodi, è possibile eseguire NSData * fileContents = [NSData dataWithContentsOfFile: @ "<yourPath>"]; NSString * myHash = [fileContents md5]; E sì, questo tirerebbe l'intero file in memoria. Se trovi una soluzione che funziona con i flussi di file, pubblicala come risposta.
Klaas,

1
Se è necessario il file hash, è necessario utilizzare CC_MD5_Init, quindi CC_MD5_Update per tutti i dati del file e, successivamente, CC_MD5_Finish.
Nickolay Olshevsky,

7
Compilando per un'architettura a 64 bit, la chiamata a dare strlenl'avvertimento: "La conversione implicita perde la precisione dei numeri interi: 'unsigned long' in 'CC_LONG' (aka 'unsigned int')"
MaxGabriel

55

È possibile utilizzare la libreria Common Crypto integrata per farlo. Ricorda di importare:

#import <CommonCrypto/CommonDigest.h>

e poi:

- (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;
}

Ho implementato il codice sopra ma durante l'esecuzione dell'applicazione si sta bloccando (CC_MD5 (cStr, strlen (cStr), digest) ----> questa riga genera un'eccezione dicendo EXC_BAD_ACCESS)
Nilesh Kumar

Verifica @wimcNilesh selfprima dell'esecuzione; se il sé è zero, si schianterà.
brandonscript,

4
Questa risposta è molto più pulita da leggere rispetto alle altre; una cosa di cui ha bisogno è un cast (int)prima, strlenad esempio (int)strlen...
brandonscript

Hay Questo è un bel voto di +1, e puoi per favore fornire anche il metodo di decrittazione md5 come la tua crittografia.
Ayaz,

@Ayaz MD5 non può essere decrittografato (almeno semplicemente con un metodo).
albanx,

9

Se le prestazioni sono importanti, è possibile utilizzare questa versione ottimizzata. È circa 5 volte più veloce di quelli con stringWithFormatoNSMutableString .

Questa è una categoria di 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;
}

0

Bene, dal momento che la gente ha chiesto una versione del flusso di file. Ho modificato un piccolo frammento fatto da Joel Lopes Da Silva che funziona con MD5, SHA1 e SHA512 E utilizza flussi. È realizzato per iOS ma funziona anche con modifiche minime anche su OSX (rimuovi il metodo ALAssetRepresentation). Può fare checksum per i file dati un percorso file o ALAssets (usando ALAssetRepresentation). Sta raggruppando i dati in piccoli pacchetti riducendo al minimo l'impatto sulla memoria indipendentemente dalla dimensione del file / dimensione dell'asset.

Si trova attualmente su github qui: https://github.com/leetal/FileHash


Il codice che Joel ha pubblicato ha una condizione di razza e sembra che il tuo possa ereditarlo. Vedi il commento che ho pubblicato sul post di Joel. joel.lopes-da-silva.com/2010/09/07/…
xyzzycoder

Grazie! Rattoppato ora. Questo non è mai stato un problema per me poiché nell'implementazione originale, l'ho sempre eseguito in un thread dedicato;)
Alexander W

0

Qualsiasi motivo per non utilizzare l'implementazione Apple: https://developer.apple.com/library/mac/documentation/Security/Conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html#//apple_ref/doc/uid/TP40011172-CH9

Cerca la Guida ai servizi di crittografia sul sito degli sviluppatori Apple.


Il link copre Common Crypto che utilizza la maggior parte delle risposte qui.
zaph,

1
Sicuramente l'algo è lo stesso. Ma nota che l'implementazione del tuo algoritmo crittografico può introdurre difetti. Ci vuole molto indurimento per renderlo corretto in tutti gli scenari. Quindi è preferibile utilizzare la versione della libreria, nel caso comune.
vpathak,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.