Thuật toán MD5 trong Objective-C


Câu trả lời:


219

md5 có sẵn trên iPhone và có thể được thêm dưới dạng bổ sung cho NSStringNSData như dưới đây.

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

BIÊN TẬP

Đã thêm NSData md5 vì tôi cần bản thân mình và nghĩ rằng đây là một nơi tốt để lưu đoạn trích nhỏ này ...

Các phương thức này được xác minh bằng các vectơ kiểm tra NIST MD5 trong http://www.nsrl.nist.gov/testdata/


Điều này có kéo toàn bộ tập tin vào bộ nhớ?
openfrog

Đây không phải là về các tập tin. Nếu bạn muốn tạo MD5 từ một tệp bằng các phương thức này, thì bạn có thể thực hiện NSData * fileContents = [NSData dataWithContentsOfFile: @ "<yourPath>"]; NSString * myHash = [fileContents md5]; Và vâng, điều này sẽ kéo toàn bộ tập tin vào bộ nhớ. Nếu bạn tìm thấy một giải pháp hoạt động với các luồng tệp, vui lòng gửi nó dưới dạng câu trả lời.
Klaas

1
Nếu bạn cần băm tệp, bạn nên sử dụng CC_MD5_Init, sau đó CC_MD5_Update cho tất cả dữ liệu tệp và sau đó - CC_MD5_Finish.
Nickolay Olshevsky

7
Biên dịch cho kiến ​​trúc 64 bit, lệnh gọi đưa strlenra cảnh báo: "Chuyển đổi ngầm định làm mất độ chính xác của số nguyên: 'dài không dấu' thành 'CC_LONG' (còn gọi là 'unsign int')"
MaxGabriel 21/03 '

55

Bạn có thể sử dụng thư viện Common Crypto tích hợp để làm như vậy. Nhớ nhập:

#import <CommonCrypto/CommonDigest.h>

và sau đó:

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

Tôi đã triển khai mã ở trên nhưng trong khi chạy ứng dụng thì nó bị lỗi (CC_MD5 (cStr, strlen (cStr), digest) ----> dòng này đang ném ngoại lệ cho biết EXC_BAD_ACCESS)
Nilesh Kumar

@wimcNilesh kiểm tra selftrước khi thực hiện; nếu bản thân không, nó sẽ sụp đổ.
brandonscript

4
Câu trả lời này dễ đọc hơn rất nhiều so với những câu hỏi khác; một điều nó cần là diễn viên (int)trước đó, strlenví dụ (int)strlen...
brandonscript

Hay Đây là upvote +1 tuyệt vời, và bạn có thể vui lòng cung cấp phương thức Giải mã md5 giống như mã hóa của bạn.
Ayaz

@Ayaz MD5 không thể giải mã (ít nhất là đơn giản với một phương thức).
albanx

9

Nếu hiệu suất là quan trọng, bạn có thể sử dụng phiên bản tối ưu hóa này. Nó nhanh hơn khoảng 5 lần so với những người có stringWithFormathoặc NSMutableString.

Đây là một thể loại của 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

Kể từ khi mọi người yêu cầu một phiên bản luồng tập tin. Tôi đã sửa đổi một đoạn nhỏ rất hay được tạo bởi Joel Lopes Da Silva hoạt động với MD5, SHA1 và SHA512 VÀ nó đang sử dụng các luồng. Nó được tạo cho iOS nhưng chỉ hoạt động với những thay đổi tối thiểu trên OSX (loại bỏ phương thức ALAssetRepftimeation). Nó có thể tạo tổng kiểm tra cho các tệp được cung cấp một filepath hoặc ALAssets (sử dụng ALAssetRepftimeation). Việc phân chia dữ liệu thành các gói nhỏ làm cho bộ nhớ tác động tối thiểu bất kể kích thước tệp / kích thước tài sản.

Hiện tại nó nằm trên github tại đây: https://github.com/leetal/FileHash


Mã mà Joel xuất bản có một điều kiện chủng tộc và có vẻ như mã của bạn có thể thừa hưởng nó. Xem bình luận mà tôi đã công bố trên bài viết của Joel. joel.lopes-da-silva.com/2010/09/07/ Cách
xyzzycoder

Cảm ơn! Vá nó lên bây giờ. Điều này chưa bao giờ là vấn đề đối với tôi vì trong lần triển khai ban đầu, tôi luôn chạy nó trong một luồng chuyên dụng;)
Alexander W

0

Bất kỳ lý do nào để không sử dụng triển khai Apple: https://developer.apple.com/l Library / mac / document / Security /Conualual / cryptoservice / GeneralPurposeCrypto / GeneralPurposeCrypto.html # / //apple_Vf / doc / uid

Tìm kiếm Hướng dẫn Dịch vụ Mật mã trên trang web dành cho nhà phát triển của Apple.


Liên kết bao gồm Crypto chung mà hầu hết các câu trả lời ở đây sử dụng.
zaph 13/03/2015

1
Chắc chắn algo là như nhau. Nhưng lưu ý rằng việc thực hiện thuật toán tiền điện tử của riêng bạn có thể đưa ra các lỗ hổng. Phải mất rất nhiều khó khăn để làm cho nó chính xác trong tất cả các kịch bản. Vì vậy, sử dụng phiên bản thư viện sẽ được ưu tiên, trong trường hợp phổ biến.
vpathak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.