【问题标题】:MD5 to UTF8 string encoding wrong charactersMD5 到 UTF8 字符串编码错误的字符
【发布时间】:2014-05-30 13:37:23
【问题描述】:

我需要转换字符串

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?`·ZuÜ

改为

PXñ¯ƒ^c?`œ·ZuÜ

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

【问题讨论】:

    标签: ios objective-c nsstring md5


    【解决方案1】:

    字符“œ”(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?

    【讨论】:

    • 我刚刚测试了我编写的示例代码,但我无法使其工作,我认为您的 MD5 可能会给出无效的 UTF8 字符。您是如何获得在问题中复制的第一个编码的?
    • 这是服务器想要返回的字符串。取自 .NET 中的服务器代码。
    • 我认为您的编码可能是 CP-1252 (en.wikipedia.org/wiki/Windows-1252)(可能转换为 UTF8?)。您仍然需要弄清楚字节 0x00-0x1F 是如何处理的。
    【解决方案2】:

    你的计划有无可救药的缺陷。您的 MD5 摘要是任意字节序列。试图将任意字节序列转换为字符串从一开始就注定要失败。大多数任意字节序列不是有效的 UTF-8。不仅包含 nul 字节的序列,而且大多数包含不碰巧在 ASCII 范围内的字符的序列。

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

    return [NSData dataWithBytes:hashBuffer 长度:CC_MD5_DIGEST_LENGTH];

    【讨论】:

      猜你喜欢
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-01
      • 1970-01-01
      • 2012-08-20
      • 2017-03-08
      • 2010-12-02
      相关资源
      最近更新 更多