iphone - tabla - Cómo convertir un NSString en valores hexadecimales
hexadecimal online (8)
Me gustaría convertir un NSString normal en un NSString con los valores hexadecimales (lo que supongo que son) ASCII y viceversa.
Necesito producir el mismo resultado que los métodos Java a continuación, pero parece que no puedo encontrar la forma de hacerlo en Objective-C. He encontrado algunos ejemplos en C y C ++, pero me ha costado trabajo incorporarlos en mi código.
Aquí están los métodos de Java que estoy tratando de reproducir:
/**
* 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);
}
Actualización: gracias a la respuesta de Drawingonward, aquí está el método que escribí para crear el hex NSStrings. Me da una advertencia de "inicialización descarta calificadores del tipo de destino del puntero" en la línea de declaración de char, pero funciona.
- (NSString *)stringToHex:(NSString *)string
{
char *utf8 = [string UTF8String];
NSMutableString *hex = [NSMutableString string];
while ( *utf8 ) [hex appendFormat:@"%02X" , *utf8++ & 0x00FF];
return [NSString stringWithFormat:@"%@", hex];
}
Todavía no he tenido tiempo de escribir el método de decodificación. Cuando lo haga, editaré esto para publicarlo para cualquier otra persona interesada.
Actualización2: Entonces, el método que publiqué anteriormente en realidad no muestra lo que estoy buscando. En lugar de dar salida a valores hexadecimales en formato 0-f, en cambio, daba salida a todos los números. Finalmente volví a trabajar en este problema y pude escribir una categoría para NSString que duplica exactamente los métodos de Java que publiqué. Aquí 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
Entonces, en primer lugar, me gustaría agradecerle su respuesta. Esto me dio la primera función, mala y limpia. En el mismo espíritu, escribí el otro. Espero que te guste.
@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'';
}
Gracias a todos los que contribuyeron en este hilo. Fue una gran ayuda para mí. Como las cosas se han movido un poco desde la publicación original, aquí está mi implementación actualizada para iOS 6. Fui con el enfoque de categorías, pero decidí dividir la carga entre NSData y NSString. Comentarios bienvenidos.
En primer lugar, la mitad NSString, que maneja la decodificación de una cadena codificada hexadecimal en un objeto 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
Los cambios fueron principalmente por la eficiencia: una aritmética de puntero antigua y simple significa que podría asignar todo el buffer de una sola vez y llenarlo byte a byte. Luego todo se pasa a NSData de una vez.
La parte de codificación, en NSData, se ve así:
@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
Una vez más, algunos cambios menores, aunque sospecho que no hay ganancias de eficiencia aquí. El uso de "% 0.2hhx" resolvió todos los problemas de falta de cero inicial y garantiza que solo se produzca un byte único a la vez.
Espero que esto ayude a la siguiente persona a tomar esto!
Hay un problema con su método stringToHex: deja caer los primeros 0 e ignora los 00. Solo como una solución rápida, hice lo siguiente:
+ (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];
}
Mi entrada fue una cadena de dígito base10, y la salida debería ser la representación hexadecimal en formato de cadena. Ejemplos:
- @ "10" -> @ "A"
- @ "1128" -> @ "468"
- @ "1833828235" -> @ "6D4DFF8B"
Implementación:
+ (NSString *) stringToHex:(NSString *)str{
NSInteger result = [str integerValue];
NSString *hexStr = (result)?@"":@"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;
}
Para estas líneas de Java
utf8 = s.getBytes(ENCODING_UTF8);
new String(decodedHexString, ENCODING_UTF8);
Los equivalentes de Objective-C serían
utf8 = [s UTF8String];
[NSString initWithUTF8String:decodedHexString];
Para hacer un NSString con la representación hexadecimal de una cadena de caracteres:
NSMutableString *hex = [NSMutableString string];
while ( *utf8 ) [hex appendFormat:@"%02X" , *utf8++ & 0x00FF];
Tendrás que hacer tu propia función decodeHex. Simplemente retire dos caracteres de la cadena y, si son válidos, agregue un byte al resultado.
Tal vez debería usar NSString
dataUsingEncoding:
para codificar e initWithData:length:encoding:
para decodificar. Depende de dónde obtengas los datos.
Una posible solución:
+(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;
}
La forma perfecta y corta de convertir nsstring en valores hexadecimales
NSMutableString *tempHex=[[NSMutableString alloc] init];
[tempHex appendString:@"0xD2D2D2"];
unsigned colorInt = 0;
[[NSScanner scannerWithString:tempHex] scanHexInt:&colorInt];
lblAttString.backgroundColor=UIColorFromRGB(colorInt);
La macro utilizada para este código es ----
#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]