MD5到UTF8字符串编码错误的字符

时间:2014-05-30 13:37:23

标签: ios objective-c nsstring md5

我需要转换字符串

NSString * password = @"."

在此字符串中

PXñ¯ƒc?`œ·ZuÜ

通过MD5转换。

使用此NSString类别

- (NSString *)MD5
{
    const char *cString = [self UTF8String];
    unsigned char hashBuffer[CC_MD5_DIGEST_LENGTH];

    CC_MD5(cString, (unsigned int)strlen(cString), hashBuffer);

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

    NSString *string = [hash uppercaseString];
    NSMutableString * newString = [[NSMutableString alloc] init]; //will contain your result-string
    int i = 0;
    while (i < [string length])
    {
        NSString * hexChar = [string substringWithRange: NSMakeRange(i, 2)];
        int value = 0;
        sscanf([hexChar cStringUsingEncoding:NSUTF8StringEncoding], "%x", &value);
        [newString appendFormat:@"%c", (char)value];
        i+=2;
    }

    return newString;
}

我获得此字符串

PXñ¯c?`·ZUU

代替

PXñ¯ƒc?`œ·ZUU

字符串略有不同,但第一个字符串没有ƒ - 字符。 想法?

2 个答案:

答案 0 :(得分:0)

字符“œ”(LATIN SMALL LIGATURE OE U + 0153)以UTF-8编码为c5 93,它需要表示两个字节,因此你的while循环会遇到麻烦。

我建议尝试以更直接的方式转换数据:

- (NSString *)MD5
{
    const char *cString = [self UTF8String];
    unsigned char hashBuffer[CC_MD5_DIGEST_LENGTH];

    CC_MD5(cString, (unsigned int)strlen(cString), hashBuffer);

    NSString * newString = [[NSString alloc] initWithBytes:hashBuffer
                                                    length:CC_MD5_DIGEST_LENGTH
                                                  encoding:NSUTF8StringEncoding];

    return newString;
}

但是,我觉得您的方案存在问题,因为我看不到如何编码包含空字节(0x00)的MD5?

答案 1 :(得分:0)

你的计划毫无希望地存在缺陷。 MD5摘要是一个任意的字节序列。尝试将任意字节序列转换为字符串从一开始就注定要失败。大多数任意字节序列有效UTF-8。不仅包含nul字节的序列,而且大多数序列包含不恰好在ASCII范围内的字符。

我建议更改方法以返回NSData对象,例如

return [NSData dataWithBytes:hashBuffer length:CC_MD5_DIGEST_LENGTH];