1

我尝试使用 md5 散列一个字符串(十六进制)。然而,输出字符串与我在 python 或 javascript (node.js) 中创建的类似输出不匹配。

输入字符串:

NSString *input = @"001856413a840871624d6c6f553885b5b16fae345c6bdd44afb26141483bff629df47dbd9ad0";


- (NSString *)md5:(NSString *)input {
// b2b22e766b849b8eb41b22ae85dc49b1
unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
const char *cStr = [input UTF8String];
CC_MD5_CTX ctx;
CC_MD5_Init(&ctx);
CC_MD5_Update(&ctx, cStr, [input length]);
CC_MD5_Final(md5Buffer, &ctx);

NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
    [output appendFormat:@"%02x",md5Buffer[i]];

return output;

}

在python中我做:

binaryCredentialString = binascii.unhexlify(input)
# Now MD5 hash the binary string    
m = hashlib.md5()
m.update(binaryCredentialString)
# Hex encode the hash to obtain the final credential string
credential = m.hexdigest()

Python 给了我正确的 md5 输出,object-C 没有。为什么是这样?

任何帮助都非常感谢 - 帕斯卡

4

2 回答 2

3

在 Python 中,您将十六进制解码回二进制,但在 Objective-C 中,您不是。将您的字符串解码为一个NSMutableData实例,然后将[data bytes](和[data length])提供给摘要函数。

于 2013-03-10T01:20:50.563 回答
3

这与dreamlax的答案基本相同,但您显然没有理解他的答案。希望我能提供帮助(但如果是这样,您应该接受他的回答)。

您的问题是您正在执行 76 字符字符串的 MD5,@"001856413a840871624d6c6f553885b5b16fae345c6bdd44afb26141483bff629df47dbd9ad0"而不是字符串编码的 38 字节二进制数据。

在 Python 中,输入md5函数的内容如下:

binaryCredentialString = binascii.unhexlify(input)

但在 ObjC 中,是这样的:

const char *cStr = [input UTF8String];

所以,你需要一个等价的unhexlify.

我会通过向类别添加方法来处理这个-(NSString *)hexlify问题。然后你可以只写这段代码,它和 Python 一样可读:NSData-(NSData *)unhexlifyNSString

- (NSString *)md5:(NSString *)input {
    NSData *binaryCredentialString = [input unhexlify];
    NSMutableData *result = [NSMutableData dataWithLength:CC_MD5_DIGEST_LENGTH];
    CC_MD5([binaryCredentialString bytes],
           [binaryCredentialString length],
           [m mutableBytes]);
    return [result hexlify];
}

那么,您如何编写这些类别?使用你的代码,以及它的反面,像这样(未经测试,需要一些验证和错误处理,但你应该明白):

@implementation NSData(hexlify)
- (NSString *)hexlify {
    unsigned char *buf = [self bytes];
    size_t len = [self length];
    NSMutableString *output = [NSMutableString stringWithCapacity:len * 2];
    for(int i = 0; i < len; i++)
        [output appendFormat:@"%02x",buf[i]];
    return [NSData dataWithData:output];
}
@end

static unsigned char unhexchar(char c) {
    if (c <= '9') return c - '0';
    if (c <= 'F') return c - 'A' + 10;
    return c - 'a' + 10;
}

@implementation NSString(hexlify)
- (NSData *)unhexlify {
    const char *cStr = [self UTF8String];
    size_t len = [self length];
    NSMutableData *output = [NSMutableData dataWithLength:len / 2];
    unsigned char *buf = [output mutableBytes];
    for(int i = 0; i < len / 2; i++)
        buf[i] = unhexchar(cStr[i*2]) * 16 + unhexchar(cStr[i*2+1]);
    return [NSString stringWithString:output];
}
@end

但我确信通过一些搜索,您可以找到这两种方法的干净、经过测试和优化的实现,而不是自己编写它们。例如,在 SO 上查看这个问题这个问题以及其他各种问题。

于 2013-03-10T02:56:34.823 回答