Python 对象C中的MD5与结果不匹配

Python 对象C中的MD5与结果不匹配,python,objective-c,hash,md5,Python,Objective C,Hash,Md5,我尝试使用md5散列字符串十六进制。但是,输出字符串与我在python或javascript node.js中创建的类似输出不匹配 输入字符串: NSString *input = @"001856413a840871624d6c6f553885b5b16fae345c6bdd44afb26141483bff629df47dbd9ad0"; - (NSString *)md5:(NSString *)input { // b2b22e766b849b8eb41b22ae85dc49b1 un

我尝试使用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返回了正确的md5输出,而object-C没有。为什么会这样

非常感谢您的帮助
-Pascal在Python中是将十六进制解码回二进制,但在Objective-C中不是。将字符串解码为NSMutableData实例,然后向摘要函数提供[data bytes]和[data length]。

在Python中,您将十六进制解码回二进制,但在Objective-C中,您没有。将字符串解码为NSMutableData实例,然后向摘要函数提供[data bytes]和[data length]。

这与dreamlax的答案基本相同,但您显然不理解他的答案。希望我能帮忙,但如果是这样,你应该接受他的回答

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

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

binaryCredentialString = binascii.unhexlify(input)
但在ObjC中,是这样的:

const char *cStr = [input UTF8String];
所以,你需要一个相当于unexlify的

我会通过将-NSString*hexlify方法添加到NSData,并通过categories将-NSData*unexlify方法添加到NSString来处理这个问题。然后您可以编写以下代码,其可读性与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

但我相信,只要稍加搜索,您就可以找到这两种方法的干净、经过测试和优化的实现,而不是自己编写它们。例如,你看,还有其他的一些人。这与dreamlax的答案基本相同,但你显然不理解他的答案。希望我能帮忙,但如果是这样,你应该接受他的回答

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

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

binaryCredentialString = binascii.unhexlify(input)
但在ObjC中,是这样的:

const char *cStr = [input UTF8String];
所以,你需要一个相当于unexlify的

我会通过将-NSString*hexlify方法添加到NSData,并通过categories将-NSData*unexlify方法添加到NSString来处理这个问题。然后您可以编写以下代码,其可读性与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

但我相信,只要稍加搜索,您就可以找到这两种方法的干净、经过测试和优化的实现,而不是自己编写它们。例如,请参阅,以及SO上的各种其他内容。

嗨,dreamlax,感谢您的回复。我已经试过了,它给了我同样的结果!?!您是否将十六进制或字符串的字符解码为NSData对象?不,我没有解码!在object-c中实现这一点的最佳方法是什么?嗨,dreamlax,感谢您的回复。我已经试过了,它给了我同样的结果!?!您是否将十六进制或字符串的字符解码为NSData对象?不,我没有解码!在object-c中实现这一点的最佳方法是什么?附带说明:如果只有一个数据缓冲区要输入哈希,只需使用一步CC_MD5而不是单独的Init、Update、Final函数。附带说明:如果只有一个数据缓冲区要输入哈希,只需使用一步CC_MD5而不是单独的Init、Update、,最终的函数。你得到+1,因为我懒得寻找一个不精确的方法。@dreamlax:我做过的每个ObjC项目,我首先要做的事情之一就是添加这两个类别。你可能会认为我会找到一些现成的东西,或者创建一个完善的版本,然后自己在GitHub上签入它,但不,每次我都做同样的搜索。所以我在这方面做得很好你会得到+1,因为我懒得去寻找一个不精确的方法。@dreamlax:我做过的每个ObjC项目,我首先要做的事情之一就是添加这两个类别。你可能会认为我会找到一些现成的东西,或者创建一个完善的版本,然后自己在GitHub上签入它,但不,每次我都做同样的搜索。所以我在这方面做得很好