2010-06-16 9 views
26

Je voudrais convertir un NSString régulier en NSString avec les valeurs hexadécimales ASCII (ce que je suppose être) et inversement.Comment convertir un NSString en valeurs hexadécimales

J'ai besoin de produire la même sortie que les méthodes Java ci-dessous, mais je n'arrive pas à trouver un moyen de le faire en Objective-C. J'ai trouvé quelques exemples en C et C++ mais j'ai eu du mal à les intégrer dans mon code.

Voici les méthodes Java, je suis en train de reproduire:

/** 
* Encodes the given string by using the hexadecimal representation of its UTF-8 bytes. 
* 
* @param s The string to encode. 
* @return The encoded string. 
*/ 
public static String utf8HexEncode(String s) { 
    if (s == null) { 
     return null; 
    } 
    byte[] utf8; 
    try { 
     utf8 = s.getBytes(ENCODING_UTF8); 
    } catch (UnsupportedEncodingException x) { 
     throw new RuntimeException(x); 
    } 
    return String.valueOf(Hex.encodeHex(utf8)); 
} 

/** 
* Decodes the given string by using the hexadecimal representation of its UTF-8 bytes. 
* 
* @param s The string to decode. 
* @return The decoded string. 
* @throws Exception If an error occurs. 
*/ 
public static String utf8HexDecode(String s) throws Exception { 
if (s == null) { 
    return null; 
} 
    return new String(Hex.decodeHex(s.toCharArray()), ENCODING_UTF8); 
} 

Mise à jour: Merci à de drawnonward réponse ici est la méthode que j'ai écrit pour créer les NSStrings hexagonaux. Il me donne un avertissement "Initialisation rejette les qualificatifs de type cible de pointeur" sur la ligne de déclaration char, mais cela fonctionne.

- (NSString *)stringToHex:(NSString *)string 
{ 
    char *utf8 = [string UTF8String]; 
    NSMutableString *hex = [NSMutableString string]; 
    while (*utf8) [hex appendFormat:@"%02X" , *utf8++ & 0x00FF]; 

    return [NSString stringWithFormat:@"%@", hex]; 
} 

N'a pas eu le temps d'écrire la méthode de décodage pour le moment. Quand je le ferai, je l'éditerai pour l'afficher pour toute personne intéressée.

Update2: La méthode que j'ai affichée ci-dessus ne produit donc pas ce que je recherche. Au lieu de sortir des valeurs hexadécimales au format 0-f, il a plutôt émis tous les nombres. J'ai finalement travaillé sur ce problème et j'ai pu écrire une catégorie pour NSString qui duplique exactement les méthodes Java que j'ai publiées. Ici, il est:

// 
// NSString+hex.h 
// Created by Ben Baron on 10/20/10. 
// 

@interface NSString (hex) 

    + (NSString *) stringFromHex:(NSString *)str; 
    + (NSString *) stringToHex:(NSString *)str; 

@end 

// 
// NSString+hex.m 
// Created by Ben Baron on 10/20/10. 
// 

#import "NSString+hex.h" 

@implementation NSString (hex) 

+ (NSString *) stringFromHex:(NSString *)str 
{ 
    NSMutableData *stringData = [[[NSMutableData alloc] init] autorelease]; 
    unsigned char whole_byte; 
    char byte_chars[3] = {'\0','\0','\0'}; 
    int i; 
    for (i=0; i < [str length]/2; i++) { 
     byte_chars[0] = [str characterAtIndex:i*2]; 
     byte_chars[1] = [str characterAtIndex:i*2+1]; 
     whole_byte = strtol(byte_chars, NULL, 16); 
     [stringData appendBytes:&whole_byte length:1]; 
    } 

    return [[[NSString alloc] initWithData:stringData encoding:NSASCIIStringEncoding] autorelease]; 
} 

+ (NSString *) stringToHex:(NSString *)str 
{ 
    NSUInteger len = [str length]; 
    unichar *chars = malloc(len * sizeof(unichar)); 
    [str getCharacters:chars]; 

    NSMutableString *hexString = [[NSMutableString alloc] init]; 

    for(NSUInteger i = 0; i < len; i++) 
    { 
     [hexString appendString:[NSString stringWithFormat:@"%x", chars[i]]]; 
    } 
    free(chars); 

    return [hexString autorelease]; 
} 

@end 
+0

Je le code à la maison. Je l'afficherai quand je quitterai le travail à moins que quelqu'un ne me batte dessus. –

+0

Salut, je sais que c'est un vieux post. Mais je suis tombé sur votre problème auquel j'ai fait face et oui. Vos résultats pour la méthode 'stringFromHex' sont ce que je recherchais aussi. Puis-je savoir d'où provient cette méthode et y a-t-il un tutoriel? Je voudrais comprendre cette méthode, et je ne peux pas l'analyser par moi-même. Merci. –

+0

Désolé, ça fait trop longtemps, je ne m'en souviens plus. –

Répondre

21

Pour ces lignes de Java

utf8 = s.getBytes(ENCODING_UTF8); 
new String(decodedHexString, ENCODING_UTF8); 

équivalents Objective-C seraient

utf8 = [s UTF8String]; 
[NSString initWithUTF8String:decodedHexString]; 

Pour faire une NSString avec la représentation hexadécimale d'une chaîne de caractères:

NSMutableString *hex = [NSMutableString string]; 
while (*utf8) [hex appendFormat:@"%02X" , *utf8++ & 0x00FF]; 

Vous devra faire votre propre fonction decodeHex. Retirez simplement deux caractères de la chaîne et, s'ils sont valides, ajoutez un octet au résultat.

+2

Devrait être "NSMutableString * hex = [Chaîne NSMutableString];" – Berik

-1

Peut-être que vous devriez utiliser NSStringdataUsingEncoding: pour coder et décoder initWithData:length:encoding: à. Cela dépend de l'endroit où vous obtenez les données.

1

Donc, tout d'abord, je voudrais remercier drawnonward pour sa réponse. Cela m'a donné la première fonction, moyenne et propre. Dans le même esprit, j'ai écrit l'autre. J'espère que vous aimez.

@synthesize unsigned char* value= _value; 

- (NSString*) hexString 
{ 
    _value[CONSTANT]= '\0'; 
    unsigned char* ptr= _value; 

    NSMutableString* hex = [[NSMutableString alloc] init]; 
    while (*ptr) [hex appendFormat:@"%02x", *ptr++ & 0x00FF]; 

    return [hex autorelease]; 
} 

- (void) setHexString:(NSString*)hexString 
{ 
    _value[CONSTANT]= '\0'; 
    unsigned char* ptr= _value; 

    for (const char* src= [hexString cStringUsingEncoding:NSASCIIStringEncoding]; 
     *src; 
     src+=2) 
    { 
     unsigned int hexByte; 
     /*int res=*/ sscanf(src,"%02x",&hexByte); 
     *ptr++= (unsigned char)(hexByte & 0x00FF); 
    } 
    *ptr= '\0'; 
} 
8

Il existe un problème avec votre méthode stringToHex - elle supprime les 0 en tête et ignore 00s. Juste comme une solution rapide, j'ai fait ce qui suit:

+ (NSString *) stringToHex:(NSString *)str 
{ 
    NSUInteger len = [str length]; 
    unichar *chars = malloc(len * sizeof(unichar)); 
    [str getCharacters:chars]; 

    NSMutableString *hexString = [[NSMutableString alloc] init]; 

    for(NSUInteger i = 0; i < len; i++) 
    { 
     // [hexString [NSString stringWithFormat:@"%02x", chars[i]]]; /*previous input*/ 
     [hexString appendFormat:@"%02x", chars[i]]; /*EDITED PER COMMENT BELOW*/ 
    } 
    free(chars); 

    return [hexString autorelease]; 
} 
+0

Je ne me suis pas rendu compte que cela pourrait avoir causé des bogues rares et aléatoires dont je ne connaissais pas l'existence .. Merci! –

+3

Btw il y a un petit bogue dans votre code, '[hexString [NSString stringWithFormat: @"% 02x ", caractères [i]]];' devrait être '[hexString appendString: [NSString stringWithFormat: @"% 02x ", caractères [i ]]]; 'ou mieux encore [[hexString appendFormat: @"% 02x ", chars [i]];' –

+0

Je n'ai pas encore les droits d'édition, donc je ne peux pas éditer votre réponse avec le correctif –

6

Merci à tous ceux qui ont contribué à ce sujet. C'était une aide précieuse pour moi. Depuis que les choses ont bougé un peu depuis le post original, voici ma mise à jour mise en œuvre pour iOS 6. Je suis allé avec l'approche des catégories, mais j'ai choisi de répartir la charge entre NSData et NSString. Commentaires accueillis. Tout d'abord, la moitié NSString, qui gère le décodage d'une chaîne codée en hexadécimal dans un objet NSData.

@implementation NSString (StringToHexData) 

// 
// Decodes an NSString containing hex encoded bytes into an NSData object 
// 
- (NSData *) stringToHexData 
{ 
    int len = [self length]/2; // Target length 
    unsigned char *buf = malloc(len) 
    unsigned char *whole_byte = buf; 
    char byte_chars[3] = {'\0','\0','\0'}; 

    int i; 
    for (i=0; i < [self length]/2; i++) { 
     byte_chars[0] = [self characterAtIndex:i*2]; 
     byte_chars[1] = [self characterAtIndex:i*2+1]; 
     *whole_byte = strtol(byte_chars, NULL, 16); 
     whole_byte++; 
    } 

    NSData *data = [NSData dataWithBytes:buf length:len]; 
    free(buf); 
    return data; 
} 
@end 

Les changements ont été principalement pour des raisons d'efficacité: un peu d'arithmétique de pointeur ancienne simple, signifie que je pourrais affecter tout le tampon en une seule fois, et le remplir octet par octet. Ensuite, le tout est transmis à NSData en une fois.

La partie encodage, NSData, ressemble à ceci:

@implementation NSData (DataToHexString) 

- (NSString *) dataToHexString 
{ 
    NSUInteger   len = [self length]; 
    char *    chars = (char *)[self bytes]; 
    NSMutableString * hexString = [[NSMutableString alloc] init]; 

    for(NSUInteger i = 0; i < len; i++) 
     [hexString appendString:[NSString stringWithFormat:@"%0.2hhx", chars[i]]]; 

    return hexString; 
} 
@end 

Encore une fois, quelques modifications mineures, bien que je soupçonne pas de gains d'efficacité ici. L'utilisation de "% 0.2hhx" a résolu tous les problèmes de zéro de début manquants et garantit que seul un octet unique est sorti à la fois.

Espérons que cela aidera la prochaine personne à le prendre!

27

La façon parfaite et court pour convertir NSString aux valeurs hexadécimaux

NSMutableString *tempHex=[[NSMutableString alloc] init]; 

[tempHex appendString:@"0xD2D2D2"]; 

unsigned colorInt = 0; 

[[NSScanner scannerWithString:tempHex] scanHexInt:&colorInt]; 

lblAttString.backgroundColor=UIColorFromRGB(colorInt); 

La macro utilisée pour ce code est ----

#define UIColorFromRGB(rgbValue) 
[UIColor \colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \ 
green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \ 
blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0] 
+1

votre implémentation de la macro UIColorFromRGB avec votre réponse –

+0

Salut @JasperBlues J'ai mis à jour mon message avec la macro requise – Prasanna

3

Une solution possible:

+(NSString*)hexFromStr:(NSString*)str 
{ 
    NSData* nsData = [str dataUsingEncoding:NSUTF8StringEncoding]; 
    const char* data = [nsData bytes]; 
    NSUInteger len = nsData.length; 
    NSMutableString* hex = [NSMutableString string]; 
    for(int i = 0; i < len; ++i)[hex appendFormat:@"%02X", data[i]]; 
    return hex; 
} 
+0

'const' est incorrect ici. –

0

Mon entrée était une chaîne de caractères base10, et la sortie devrait être la représentation hexadécimale en format de chaîne. Exemples:

  • @ "10" -> @ "A"
  • @ "1128" -> @ "468"
  • @ "1833828235" -> @ "6D4DFF8B"

Mise en œuvre:

+ (NSString *) stringToHex:(NSString *)str{ 
NSInteger result = [str integerValue]; 
NSString *hexStr = (result)[email protected]"":@"0"; 

while (result!=0) { 
    NSInteger reminder = result % 16; 

    if(reminder>=0 && reminder<=9){ 
     hexStr = [[NSString stringWithFormat:@"%ld",(long)reminder] stringByAppendingString:hexStr]; 
    }else if(reminder==10){ 
     hexStr = [@"A" stringByAppendingString:hexStr]; 
    }else if(reminder==11){ 
     hexStr = [@"B" stringByAppendingString:hexStr]; 
    }else if(reminder==12){ 
     hexStr = [@"C" stringByAppendingString:hexStr]; 
    }else if(reminder==13){ 
     hexStr = [@"D" stringByAppendingString:hexStr]; 
    }else if(reminder==14){ 
     hexStr = [@"E" stringByAppendingString:hexStr]; 
    }else{ 
     hexStr = [@"F" stringByAppendingString:hexStr]; 
    } 

    result /=16; 
} 

return hexStr; 

}