Algorytm MD5 w Objective-C


Odpowiedzi:


219

md5 jest dostępny na iPhone'a i można go dodać jako dodatek do ie NSStringi NSDatajak poniżej.

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

EDYTOWAĆ

Dodałem NSData md5, ponieważ sam go potrzebowałem i pomyślałem, że to dobre miejsce na zapisanie tego małego fragmentu ...

Metody te są weryfikowane przy użyciu wektorów testowych NIST MD5 w http://www.nsrl.nist.gov/testdata/


Czy to powoduje wciągnięcie całego pliku do pamięci?
openfrog

Tu nie chodzi o pliki. Jeśli chcesz utworzyć MD5 z pliku za pomocą tych metod, możesz wykonać NSData * fileContents = [NSData dataWithContentsOfFile: @ "<yourPath>"]; NSString * myHash = [fileContents md5]; I tak, to spowodowałoby wciągnięcie całego pliku do pamięci. Jeśli znajdziesz rozwiązanie, które działa ze strumieniami plików, prześlij je jako odpowiedź.
Klaas

1
Jeśli potrzebujesz haszowania pliku, powinieneś użyć CC_MD5_Init, następnie CC_MD5_Update dla wszystkich danych pliku, a następnie - CC_MD5_Finish.
Nickolay Olshevsky

7
Kompilując dla architektury 64-bitowej, wywołanie strlendaje ostrzeżenie: „Niejawna konwersja traci precyzję liczby całkowitej: 'unsigned long' na 'CC_LONG' (aka 'unsigned int')”
MaxGabriel

55

W tym celu możesz skorzystać z wbudowanej biblioteki Common Crypto. Pamiętaj, aby zaimportować:

#import <CommonCrypto/CommonDigest.h>

i wtedy:

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

Zaimplementowałem powyższy kod, ale podczas uruchamiania aplikacji dochodzi do awarii (CC_MD5 (cStr, strlen (cStr), digest) ----> ta linia rzuca wyjątek mówiąc: EXC_BAD_ACCESS)
Nilesh Kumar

@wimcNilesh sprawdź selfprzed wykonaniem; jeśli self jest zerowe, to się rozbije.
brandonscript

4
Ta odpowiedź jest dużo bardziej czytelna niż inne; jedyną rzeczą, jakiej potrzebuje, jest obsada, (int)zanim strlennp. (int)strlen...
brandonscript

Hay To fajne +1 upvote, I czy możesz również podać metodę deszyfrowania md5 taką samą, jak szyfrowanie twojego.
Ayaz

@Ayaz MD5 nie można odszyfrować (przynajmniej za pomocą metody).
albanx

9

Jeśli ważna jest wydajność, możesz użyć tej zoptymalizowanej wersji. Jest około 5 razy szybszy niż te z stringWithFormatlub NSMutableString.

To jest kategoria 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

Cóż, ponieważ ludzie pytali o wersję strumieniową plików. Zmodyfikowałem ładny mały fragment autorstwa Joela Lopesa Da Silvy, który działa z MD5, SHA1 i SHA512 ORAZ korzysta ze strumieni. Jest stworzony dla iOS, ale działa również z minimalnymi zmianami na OSX (usuń metodę ALAssetRepresentation). Może tworzyć sumy kontrolne dla plików, którym podano ścieżkę do pliku lub ALAssets (używając ALAssetRepresentation). Dzieli dane na małe pakiety, dzięki czemu wpływ na pamięć jest minimalny, niezależnie od rozmiaru pliku / rozmiaru zasobu.

Obecnie znajduje się na github tutaj: https://github.com/leetal/FileHash


Kod, który opublikował Joel, ma stan wyścigu i wygląda na to, że Twój może go odziedziczyć. Zobacz komentarz, który opublikowałem w poście Joela. joel.lopes-da-silva.com/2010/09/07/…
xyzzycoder

Dzięki! Poprawiłem to teraz. Nigdy nie stanowiło to dla mnie problemu, ponieważ w oryginalnej realizacji zawsze uruchamiałem ją w dedykowanym wątku;)
Alexander W

0

Każdy powód, aby nie korzystać z implementacji Apple: https://developer.apple.com/library/mac/documentation/Security/Conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html#//apple_ref/doc/uid/TP40011172-CH9-SW1

Wyszukaj Przewodnik po usługach kryptograficznych w witrynie programistów Apple.


Link obejmuje Common Crypto, z którego korzysta większość odpowiedzi.
zaph

1
Jasne, algo jest takie samo. Pamiętaj jednak, że implementacja własnego algorytmu kryptograficznego może wprowadzić wady. Poprawność wszystkich scenariuszy wymaga dużo pracy . Dlatego w typowym przypadku preferowane jest używanie wersji bibliotecznej.
vpathak
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.