ASCII в NSData - PullRequest
       20

ASCII в NSData

0 голосов
/ 24 ноября 2010

Это еще одна проблема в моей проблеме с MD5.Я знаю, что проблема в символе ASCII © (0xa9, 169).Либо это способ вставки символа в строку, либо проблема с более старшим или младшим байтом.

Если я

 NSString *source = [NSString stringWithFormat:@"%c", 0xa9];

    NSData *data = [source dataUsingEncoding:NSASCIIStringEncoding];

    NSLog(@"\n\n ############### source %@ \ndata desc %@", source, [data description]);

CC_MD5([data bytes], [data length], 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]
   ];

Результат:

######### source ©

[data description] = (null)
md5: d41d8cd98f00b204e9800998ecf8427e

значения: int 169 char ©

Когда я изменяю кодировку на

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];

Результат:

######### source ©

[описание данных] = "<" c2>
md5: 6465dad1d31752be3f3283e8f70feef7

Когда я изменяюкодировка

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

Результат ############### source © len 2 [data description] = "<" c2a9>
md5: a541ecda3d4c67f1151cad5075633423

Когда я запускаю ту же функцию в Java, я получаю

">>>>> msg ## \ 251 \ 251
md5 a252c2c85a9e7756d5ba5da9949d57ed

Вопрос в том, чтонаилучший способ получить тот же байт в objC, что и в Java?

Ответы [ 2 ]

6 голосов
/ 24 ноября 2010

«ASCII to NSData» не имеет смысла, потому что ASCII - это кодировка;если у вас есть закодированные символы, то у вас есть данные.

Кодировка - это преобразование идеальных символов Unicode (кодовые точки) в одно-или более-байтовые единицы (кодовые единицы), возможно, в последовательности, такие как UTFСуррогатные пары -16.

NSString - более или менее идеальный объект Unicode.Он содержит символов строки в Unicode, независимо от кодировки *.

ASCII - кодировка.UTF-8 также является кодировкой.Когда вы запрашиваете строку для ее UTF8String, вы просите ее закодировать ее символы как UTF-8.

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source length]];

В результате получается

 ######### source ©
 [data description] = "<"c2>

Это потому, что вы прошли неправильную длину.Длина строки (в символах) не совпадает с количеством единиц кода (в данном случае байтов) в некоторой кодировке.

Правильная длина strlen([source UTF8String]), но она проще для вас и быстрее ввремя выполнения, чтобы использовать dataUsingEncoding:, чтобы запросить строку для создания объекта NSData.

Когда я изменяю кодировку на

NSData *data = [NSData dataWithBytes:[source UTF8String] length:[source lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

Вы не сделалиизменить кодировкуВы все еще кодируете его как UTF-8.

Используйте dataUsingEncoding:.

Вопрос в том, каков наилучший способ получить тот же байт в objC, как и вJava?

Использовать ту же кодировку.

Не существует такого понятия, как «расширенный ASCII».Существует несколько различных кодировок, которые основаны (или, по крайней мере, совместимы с) ASCII, включая ISO 8859-1, ISO 8859-9, MacRoman, кодовую страницу Windows 1252 и UTF-8.Вам нужно решить, какой из них вы имеете в виду, и указать строке для кодирования символов с этим.

Еще лучше, продолжайте использовать UTF-8 - это почти всегда правильный выбор для текста в основном ASCII - и измените свойВместо этого Java-код.

NSData *data = [source dataUsingEncoding:NSASCIIStringEncoding];

Результат:

[data description] = (null)

Истинный ASCII может кодировать только 128 возможных символов.Юникод включает в себя все ASCII без изменений, поэтому первые 128 кодовых точек в Юникоде - это то, что может кодировать ASCII.Что-нибудь еще, ASCII не может кодировать.

Я видел NSASCIIStringEncoding, ведущий себя как эквивалент NSISOLatin1StringEncoding раньше;Похоже, они могли изменить его на чистую кодировку ASCII, и если это так, то это хорошо.В ASCII нет символа авторского права.То, что вы видите здесь, является правильным результатом.


* Это не совсем так;символы обозначаются как UTF-16, поэтому любые символы вне базовой многоязычной плоскости представляются в виде суррогатных пар, а не целых символов, как это было бы в действительно идеальном строковом объекте.Это компромисс.В Swift встроенный тип String является идеальным идеальным объектом Unicode;символы являются символами, никогда не разделяются, пока не закодированы.Но, работая с NSString (будь то в Swift или в Objective-C), вы должны рассматривать его как идеальную строку.

1 голос
/ 27 ноября 2010

Благодаря объяснению Г.Бегана в другом посте, я смог сделать это вместе.

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

}

...