Как преобразовать значения NSString в шестнадцатеричные значения

Я хотел бы преобразовать обычный NSString в NSString с (как я предполагаю,) шестнадцатеричными значениями ASCII и обратно.

Мне нужно создать тот же результат, что и методы Java ниже, но я не могу найти способ сделать это в Objective-C. Я нашел несколько примеров на C и C ++, но мне было трудно работать с ними в моем коде.

Вот методы Java, которые я пытаюсь воспроизвести:

/** * 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); } 

Обновление: благодаря ответу drawonward вот метод, который я написал для создания шестнадцатеричных NSStrings. Это дает мне предупреждение «Инициализация отбрасывает квалификаторы из указателя целевого типа» в строке объявления char, но оно работает.

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

Еще не успел написать метод декодирования. Когда я это сделаю, я отредактирую это, чтобы опубликовать его для всех, кого это интересует.

Update2: Таким образом, метод, который я опубликовал выше, фактически не выводит то, что я ищу. Вместо вывода шестнадцатеричных значений в формате 0-f вместо этого выводились все числа. Я, наконец, вернулся к работе над этой проблемой и смог написать категорию для NSString, которая точно дублирует методы Java, которые я опубликовал. Вот:

 // // 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 

Для этих строк Java

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

Объективные C-эквиваленты были бы

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

Чтобы создать NSString с шестнадцатеричным представлением символьной строки:

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

Вам нужно будет сделать свою собственную функцию decodeHex. Просто вытащите два символа из строки и, если они действительны, добавьте байт к результату.

Идеальный и короткий способ преобразования nsstring в шестнадцатеричные значения

 NSMutableString *tempHex=[[NSMutableString alloc] init]; [tempHex appendString:@"0xD2D2D2"]; unsigned colorInt = 0; [[NSScanner scannerWithString:tempHex] scanHexInt:&colorInt]; lblAttString.backgroundColor=UIColorFromRGB(colorInt); 

Макрос, используемый для этого кода, составляет —-

 #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] 

Существует проблема с вашим методом stringToHex – он пропускает ведущие 0 и игнорирует 00s. Как быстро, я сделал следующее:

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

Спасибо всем, кто внес свой вклад в эту тему. Это очень помогло мне. Поскольку некоторые вещи немного изменились со времени первоначального сообщения, вот моя обновленная версия для iOS 6. Я пошел с подходом категорий, но решил разделить нагрузку между NSData и NSString. Комментарии приветствуются.

Во-первых, половина NSString, которая обрабатывает декодирование шестнадцатеричной кодированной строки в объект 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 

Изменения были в основном для эффективности: некоторые простые старомодные арифметические указатели означали, что я мог бы выделить весь буфер за один раз и заполнить его байтом байтом. Затем все это передается NSData за один раз.

Кодирующая часть в NSData выглядит следующим образом:

 @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 

Опять же, некоторые незначительные изменения, хотя я и не подозреваю, что эффективность здесь не повышается. Использование «% 0.2hhx» разрешило все проблемы отсутствия нулевого начального нуля и гарантирует, что одновременно выводится только один байт.

Надеюсь, это поможет следующему человеку принять это!

Одно из возможных решений:

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

Итак, во-первых, я хотел бы поблагодарить его за ответ. Это дало мне первую функцию, среднюю и чистую. В том же духе я написал другой. Надеюсь, вам понравится.

 @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'; } 

Моим входом была строка digit10, и выход должен быть шестнадцатеричным представлением в строковом формате. Примеры:

  • @ “10” -> @ “A”
  • @ “1128” -> @ “468”
  • @ “1833828235” -> @ “6D4DFF8B”

Реализация:

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

}

Возможно, вам следует использовать NSString dataUsingEncoding: для кодирования и initWithData:length:encoding: для декодирования. Зависит от того, откуда вы получаете данные.

  • Как программно изменить оттенок UIImage?
  • iPhone SDK: в чем разница между loadView и viewDidLoad?
  • Плохой URL-адрес при запросе с помощью NSURL
  • Воспроизведение музыки в фоновом режиме с помощью AVAudioplayer
  • UILongPressGestureRecognizer вызывается дважды при нажатии
  • UIPageViewController не возвращает никаких распознавателей жестов в iOS 6
  • Возможно открытие всплывающих ссылок в UIWebView?
  • Процедура отправки сообщений iOS 6 Facebook заканчивается ошибкой «remote_app_id не соответствует сохраненному id»
  • Программно включить Bluetooth в iphone sdk?
  • Есть ли способ указать позицию / индекс аргумента в NSString stringWithFormat?
  • Как использовать первый символ в качестве имени раздела
  • Давайте будем гением компьютера.