2010-11-21 104 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