Object-C中的MD5不匹配结果

时间:2013-03-10 01:17:01

标签: python objective-c hash md5

我尝试使用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输出,对象-C没有。这是为什么?

真的很感激任何帮助 - 帕斯卡尔

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

这与dreamlax的答案基本相同,但你显然不明白他的答案。希望我能提供帮助(但如果是这样,你应该接受他的回答)。

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

在Python中,您向md5函数提供的内容是:

binaryCredentialString = binascii.unhexlify(input)

但是在ObjC中,就是这样:

const char *cStr = [input UTF8String];

因此,您需要等效的unhexlify

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

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

但我确信通过一些搜索,您可以找到这两种方法的干净,经过测试和优化的实现,而不是自己编写。例如,请参阅this questionthis one以及其他各种其他内容。