当前位置:  开发笔记 > 编程语言 > 正文

如何在Cocoa中创建字符串的MD5哈希?

如何解决《如何在Cocoa中创建字符串的MD5哈希?》经验,为你挑选了3个好方法。

我知道SHA-1是首选,但这个项目要求我使用MD5.

#include 

- (NSString*) MD5Hasher: (NSString*) query {
    NSData* hashed = [query dataUsingEncoding:NSUTF8StringEncoding];
    unsigned char *digest = MD5([hashed bytes], [hashed length], NULL);
    NSString *final = [NSString stringWithUTF8String: (char *)digest];
    return final;
}

我从StackOverflow上的另一个类似问题的答案得到了这个代码,但是当程序在返回final时中断时,我从GDB得到以下错误;

(gdb) p digest
$1 = (unsigned char *) 0xa06310e4 "\0206b\260/\336\316^\021\b\a/9\310\225\204"
(gdb) po final
Cannot access memory at address 0x0
(gdb) po digest

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xb0623630
0x98531ed7 in objc_msgSend ()
The program being debugged was signaled while in a function called from GDB.
GDB has restored the context to what it was before the call.
To change this behavior use "set unwindonsignal off"
Evaluation of the expression containing the function
(_NSPrintForDebugger) will be abandoned.

我无法理解它.



1> Grant Paul..:

这是我使用的类别:

的NSString + MD5.h

@interface NSString (MD5)

- (NSString *)MD5String;

@end

的NSString + MD5.m

#import 

@implementation NSString (MD5)

- (NSString *)MD5String {
    const char *cStr = [self UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5( cStr, (CC_LONG)strlen(cStr), result );

    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

用法

NSString *myString = @"test";
NSString *md5 = [myString MD5String]; // returns NSString of the MD5 of test


也许使用常量CC_MD5_DIGEST_LENGTH并转换为CC_LONG以获得64位兼容性`const char*cStr = [self UTF8String]; unsigned char结果[CC_MD5_DIGEST_LENGTH]; CC_MD5(cStr,(CC_LONG)strlen(cStr),result);`

2> Peter Hosey..:

cdespinosa和irsk已经为您展示您的实际问题,所以让我经过你GDB成绩单:

(gdb) p digest
$1 = (unsigned char *) 0xa06310e4 "\0206b\260/\336\316^\021\b\a/9\310\225\204"

您已打印digest为C字符串.你可以在这里看到这个字符串是原始字节; 因此所有的八进制转义(例如\020,\225)和几个标点字符(/^).它不是您期望的可打印ASCII十六进制表示.你很幸运,它没有零字节; 否则,你不会打印整个哈希.

(gdb) po final
Cannot access memory at address 0x0

finalnil.这是有道理的,因为上面的字符串无效UTF-8; 再次,它只是原始数据字节.stringWithUTF8String:需要UTF-8编码的文本字符串; 你没有给它一个,所以它返回了nil.

要传递原始数据,您需要使用NSData.在这种情况下,我想你想的十六进制表示,所以你需要创建自己irsk的方式向您展示.

最后,考虑一下您的输入没有散列到有效的UTF-8字符串是多么幸运.如果有,你就不会注意到这个问题.您可能希望使用此输入为此哈希方法构造单元测试.

(gdb) po digest

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xb0623630
0x98531ed7 in objc_msgSend ()

你的程序崩溃了(具体问题:"访问不良","无效地址")objc_msgSend.这是因为digest要么根本不是Cocoa/CF对象,要么是一个但是被释放了.在这种情况下,它是因为digest不是Cocoa对象; 它是一个C字节数组,如p digest上面的行所示.

请记住,Objective-C是C的超集.所有C都保持不变.这意味着有C数组(例如char [])和Cocoa的NSArrays并排.此外,由于NSArray来自Cocoa框架,而不是Objective-C语言,因此无法使NSArray对象与C数组互换:您不能在Cocoa数组上使用下标运算符,也不能发送Objective-C消息到C数组.



3> Peter Lapisu..:

Facebook使用这个

#import 

+ (NSString*)md5HexDigest:(NSString*)input {
    const char* str = [input UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, strlen(str), result);

    NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
    for(int i = 0; i

或实例方法

- (NSString *)md5 {
    const char* str = [self UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (CC_LONG)strlen(str), result);

    NSMutableString *ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
    for(int i = 0; i


如果您不知道常量CC_MD5_DIGEST_LENGTH的来源,可以通过在文件中导入CommonCrypto/CommonDigest.h找到它
推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有