2010-11-21 7 views
2

J'ai une chaîneMD5 avec ASCII Char

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

et munge Je l'appelle

-(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; 
} 

en raison de 0xA9 * src = [UTF8String source] ne crée pas char qui représente la chaîne , renvoyant ainsi un munge qui n'est pas comparable avec d'autres plates-formes.

J'ai essayé d'encoder le char avec NSASCIIStringEncoding mais il a cassé le code. Comment appeler CC_MD5 avec une chaîne qui a des caractères ASCII et obtient le même hachage que dans Java?


mise à jour à la demande de code:

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 

Résultat >>>>> 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]); 

Résultat >>>> objC msg ## int 169 char © md5: 9b759040321a408a5c7768b4511287a6

** Comme indiqué précédemment - sans le 0xa9 les hachages dans Java et ObjC sont les mêmes. Je suis en train d'obtenir le hachage pour 0xA9 même en Java et ObjC


code 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(); 
} 

Je crois que mon problème est avec l'utilisation NSData withEncoding par opposition à un C char [] ou l'octet Java []. Alors, quelle est la meilleure façon de lancer mes propres octets dans un octet [] dans objC?

+0

Pourriez-vous s'il vous plaît indiquer votre question? Nous aimons voir des questions explicites ici. – Oded

+1

Merci de me guider pour devenir une meilleure liste de citoyens. –

+1

À quoi ressemble votre code Java? –

Répondre

0

Merci à l'explication de GBegan - voici ma solution

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 nécessite une chaîne C terminée par un caractère nul. Je ne pense pas que kTestASCII[] soit nécessairement terminé par un caractère nul dans votre code Objective-C. Peut-être que c'est la cause de la différence.

Essayez:

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

Résultat avec un terminateur null >>>> objC msg ## int 169 char © md5: 9b759040321a408a5c7768b4511287a6 Identique à un article précédent. –

+0

Désolé, cela n'a pas aidé. C'était juste quelque chose qui m'avait échappé comme un défaut, bien qu'apparemment bénin, dans votre code d'essai Objective-C. – GBegen

2

Le personnage que vous rencontrez des problèmes avec, ©, est l'Unicode COPYRIGHT SIGN (00A9). L'encodage UTF-8 correct de ce caractère est la séquence d'octets 0xc9 0xa9.

Vous tentez cependant de convertir à partir de la séquence mono-octet 0xa9 qui n'est pas un codage UTF-8 valide de n'importe quel caractère. Voir le tableau 3-7 de http://www.unicode.org/versions/Unicode5.2.0/ch03.pdf#G7404. Comme ce n'est pas une séquence d'octets UTF-8 valide, stringWithCString convertit votre entrée en Unicode REPLACEMENT_CHARACTER (FFFD). Lorsque ce caractère est ensuite codé en UTF-8, il donne la séquence d'octets 0xef 0xbf 0xbd. Le MD5 de cette séquence est 9b759040321a408a5c7768b4511287a6 tel que rapporté par votre exemple Objective-C.

Votre exemple Java donne un MD5 de a252c2c85a9e7756d5ba5da9949d57ed, qui montre d'une expérimentation simple est le MD5 de la séquence d'octets 0xa9, que je l'ai déjà dit n'est pas une représentation UTF-8 valide du caractère souhaité.

Je pense que nous devons voir l'implémentation de la méthode Java md5() que vous utilisez. Je soupçonne qu'il abandonne simplement les octets hauts de chaque caractère Unicode pour convertir en une séquence d'octets pour passer à la classe MessageDigest. Cela ne correspond pas à votre implémentation Objective-C lorsque vous utilisez un codage UTF-8.

Remarque: même si vous fixez votre implémentation Objective-C pour correspondre à l'encodage de votre méthode Java md5(), votre test aura besoin d'un ajustement parce que vous ne pouvez pas utiliser stringWithCString avec le NSUTF8StringEncoding codant pour convertir la séquence d'octets 0xa9 à une NSString.

MISE À JOUR

Ayant maintenant vu l'implémentation Java en utilisant la méthode getBytes dépréciée, ma recommandation est de changer la mise en œuvre Java, si possible, d'utiliser un encodage UTF-8 approprié.

Je suppose cependant que vos exigences doivent correspondre à l'implémentation Java actuelle, même si elle est incorrecte. Par conséquent, je vous suggère de dupliquer le mauvais comportement de la méthode obsolète getBytes() de Java en utilisant NSString getCharacters:range: pour récupérer un tableau de unichar s, puis de créer manuellement un tableau d'octets en prenant l'octet bas de chaque unichar.

+0

Merci - c'est ce que j'ai soupçonné. Je vais ajouter le code Java à poster. –