我尝试使用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没有。这是为什么?
真的很感激任何帮助 - 帕斯卡尔
答案 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 *)unhexlify
到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
但我确信通过一些搜索,您可以找到这两种方法的干净,经过测试和优化的实现,而不是自己编写。例如,请参阅this question,this one以及其他各种其他内容。