2010-11-21 59 views
2

我有一个字符串MD5与ASCII字符

wDevCopyright = [NSString stringWithFormat:@"Copyright: %c 1995 by WIRELESS.dev, Corp Communications Inc., All rights reserved.",0xa9]; 

,并Munge时间它我打电话

-(NSString *)getMD5:(NSString *)source 
{ 

const char *src = [source UTF8String]; 
unsigned char result[CC_MD5_DIGEST_LENGTH]; 
CC_MD5(src, strlen(src), result); 

    return [NSString stringWithFormat: 
    @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 
    result[0], result[1], result[2], result[3], 
    result[4], result[5], result[6], result[7], 
    result[8], result[9], result[10], result[11], 
    result[12], result[13], result[14], result[15] 
    ]; //ret; 
} 

因为0xa9的* SRC = [来源UTF8字符串]不创建一个代表串字符,因此返回了一个与其他平台无法比拟的模式。

我试图用NSASCIIStringEncoding对字符进行编码,但它破坏了代码。

如何用具有ASCII字符的字符串调用CC_MD5并获得与Java中相同的哈希值?


更新到代码请求:

爪哇

private static char[] kTestASCII = { 
     169 
     }; 

System.out.println("\n\n>>>>> msg## " + (char)0xa9 + " " + (char)169 + "\n md5 " + md5(new String(kTestASCII), false) //unicode = false 

结果>>>>> MSG ## \ 251 \ 251 MD5 a252c2c85a9e7756d5ba5da9949d57ed

ObjC

 char kTestASCII [] = { 
      169 
     }; 


NSString *testString = [NSString stringWithCString:kTestASCII encoding:NSUTF8StringEncoding]; 

NSLog(@">>>> objC msg## int %d char %c md5: %@", 0xa9, 169, [self getMD5:testString]); 

结果>>>> objC msg ## int 169 char©md5:9b759040321a408a5c7768b4511287a6

**如前所述 - 没有0xa9,Java和ObjC中的哈希值是相同的。我试图获得哈希值0xa9 Java和ObjC


Java的MD5码相同

private static char[] kTestASCII = { 
    169 
    }; 

md5(new String(kTestASCII), false); 

    /** 
    * Compute the MD5 hash for the given String. 
    * @param s the string to add to the digest 
    * @param unicode true if the string is unciode, false for ascii strings 
    */ 
    public synchronized final String md5(String value, boolean unicode) 
    { 
     MD5(); 
     MD5.update(value, unicode); 
     return WUtilities.toHex(MD5.finish()); 

    } 
    public synchronized void update(String s, boolean unicode) 
{ 


    if (unicode) 
    { 
     char[] c = new char[s.length()]; 
     s.getChars(0, c.length, c, 0); 
     update(c); 
    } 
    else 
    { 
     byte[] b = new byte[s.length()]; 
     s.getBytes(0, b.length, b, 0); 
     update(b); 
    } 
} 

public synchronized void update(byte[] b) 
{ 
    update(b, 0, b.length); 
} 

//-------------------------------------------------------------------------------- 

/** 
* Add a byte sub-array to the digest. 
*/ 
public synchronized void update(byte[] b, int offset, int length) 
{ 
    for (int n = offset; n < offset + length; n++) 
     update(b[n]); 
} 

/** 
* Add a byte to the digest. 
*/ 
public synchronized void update(byte b) 
{ 
    int index = (int)((count >>> 3) & 0x03f); 
    count += 8; 
    buffer[index] = b; 
    if (index >= 63) 
     transform(); 
} 

我相信我的问题是使用NSData的withEncoding,而不是一个C的char []或Java byte []。那么在objC中将自己的字节转换为byte []的最佳方法是什么?

+0

你能请注明你的问题?我们希望看到明确的问题。 – Oded 2010-11-21 14:13:37

+1

谢谢你指导我成为一个更好的名单公民。 – 2010-11-21 14:46:42

+1

你的Java代码是什么样的? – 2010-11-21 23:25:47

回答

0

由于GBegan的解释 - 这里是我的解决方案

for(int c = 0; c < [s length]; c++){ 
    int number = [s characterAtIndex:c]; 
    unsigned char c[1]; 
    c[0] = (unsigned char)number; 
    NSMutableData *oneByte = [NSMutableData dataWithBytes:&c length:1]; 
} 
0

stringWithCString要求空终止的C字符串。我不认为kTestASCII[]必然在您的Objective-C代码中以null结尾。也许这是差异的原因。

尝试:

char kTestASCII [] = { 
      169, 
      0 
     }; 
+0

带有空终止符的结果>>>> objC msg ## int 169 char©md5:9b759040321a408a5c7768b4511287a6与之前的文章相同。 – 2010-11-23 03:33:18

+0

对不起,没有帮助。这只是在我的Objective-C测试代码中跳出来的一个缺陷,虽然它显然是一个良性的缺陷。 – GBegen 2010-11-24 18:29:35

2

您有,©,是Unicode COPYRIGHT SIGN (00A9)问题的字符。该字符的正确UTF-8编码是字节序列0xc9 0xa9

但是,您正在尝试将单字节序列0xa9转换为不是任何字符的有效UTF-8编码。请参阅http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#G7404的表3-7。由于这不是有效的UTF-8字节序列,因此stringWithCString将您的输入转换为Unicode REPLACEMENT_CHARACTER (FFFD)。当这个字符被编码回UTF-8时,它会产生字节序列0xef 0xbf 0xbd。这个序列的MD5是9b759040321a408a5c7768b4511287a6,正如您的Objective-C示例所报告的那样。

您的Java示例生成a252c2c85a9e7756d5ba5da9949d57ed的MD5,简单实验显示的是字节序列0xa9的MD5,我已经注意到它不是所需字符的有效UTF-8表示。

我想我们需要看到您正在使用的Java md5()方法的实现。我怀疑它只是放弃每个Unicode字符的高字节以转换为传递给MessageDigest类的字节序列。这与您使用UTF-8编码的Objective-C实现不匹配。

注意:即使你解决您的Objective-C的实施,以配合您的Java MD5()方法的编码,测试将需要一些调整,因为你不能使用stringWithCStringNSUTF8StringEncoding编码的字节序列0xa9转换为NSString的。

UPDATE

现在已经看到了使用过时的getBytes方法的Java实现,我的建议是要改变Java实现,如果可能的话,使用正确的UTF-8编码。

但是,我怀疑你的要求是要匹配当前的Java实现,即使它是错误的。因此,我建议您通过使用NSString getCharacters:range:来检索一个unichar s的数组,重复Java不推荐使用的getBytes()方法的不良行为,然后通过获取每个unichar的低字节手动创建一个字节数组。

+0

谢谢 - 这是我所怀疑的。我将添加Java代码发布。 – 2010-11-24 22:25:50