Преобразование байтов NSData в NSString - PullRequest
2 голосов
/ 07 января 2012

Я пытаюсь создать 16-байтовый и более поздний 32-байтовый вектор инициализации в target-c (Mac OS). Я взял некоторый код о том, как создавать случайные байты и изменил его до 16 байтов, но у меня есть некоторые трудности с этим. NSData сбрасывает шестнадцатеричный код, но дамп NSString дает ноль, а NSLog cstring дает неправильное количество символов (здесь не воспроизводится то же самое в дампе).

Вот мой вывод терминала:

2012-01-07 14:29:07.705 Test3Test[4633:80f] iv hex <48ea262d efd8f5f5 f8021126 fd74c9fd>
2012-01-07 14:29:07.710 Test3Test[4633:80f] IV string: (null)
2012-01-07 14:29:07.711 Test3Test[4633:80f] IV char string t^Q¶�^��^A

Вот основная программа:

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    //NSString *iv_string = [NSString stringWithCString:iv encoding:NSUTF8StringEncoding];
    testclass *obj = [testclass alloc];
    NSData *iv_data = [obj createRandomNSData];
    //[iv_string dataUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"iv hex %@",iv_data);

    //NSString *iv_string = [[NSString alloc] initWithBytes:[iv_data bytes] length:16 encoding:NSUTF8StringE$
    NSString *iv_string = [[NSString alloc] initWithData:iv_data encoding:NSUTF8StringEncoding];
    NSLog(@"IV string: %@",iv_string);
    NSLog(@"IV char string %.*s",[iv_data bytes]);

    return 0;
]

(я оставил в вышеупомянутом некоторый прокомментированный код, который я пробовал и тоже не работал).

Ниже мой генератор случайных чисел, взятый из примера переполнения стека:

@implementation testclass
-(NSData*)createRandomNSData
{
    int twentyMb           = 16;
    NSMutableData* theData = [NSMutableData dataWithCapacity:twentyMb];
    for( unsigned int i = 0 ; i < twentyMb/4 ; ++i )
    {
            u_int32_t randomBits = arc4random();
            [theData appendBytes:(void*)&randomBits length:4];
    }
    NSData *data = [NSData dataWithData:theData];
    [theData dealloc];
    return data;
}
@end

Я действительно совершенно не понимаю, в чем здесь может быть проблема. Если у меня есть данные в байтах, они должны преобразовываться в строку или не обязательно? Я рассмотрел соответствующие примеры здесь на stackoverflow, но ни один из них не работал в этой ситуации.

Спасибо, Илия

Ответы [ 2 ]

7 голосов
/ 08 января 2012

Произвольная последовательность байтов может не соответствовать кодировке UTF8 Как отмечает @Joachim Isaksson, редко есть причина для преобразования в строки таким способом. Если вам нужно хранить случайные данные в виде строки, вы должны использовать схему кодирования, такую ​​как Base64, сериализовать NSData в plist или подобный подход. Вы также не можете просто использовать cstring, поскольку NULL допустимо внутри случайной последовательности байтов, но недопустимо внутри cstring.

Вам не нужно создавать свой собственный создатель случайных байтов на Mac или iOS. Есть один встроенный, называемый SecRandomCopyBytes(). Например (из Правильное шифрование с помощью AES с CommonCrypto ):

+ (NSData *)randomDataOfLength:(size_t)length {
  NSMutableData *data = [NSMutableData dataWithLength:length];

  int result = SecRandomCopyBytes(kSecRandomDefault, 
                                  length,
                                  data.mutableBytes);
  NSAssert(result == 0, @"Unable to generate random bytes: %d",
           errno);

  return data;
}
2 голосов
/ 08 января 2012

При преобразовании NSData в NSString с использованием кодировки UTF8 вы не обязательно получите одинаковое количество байтов, поскольку не все двоичные значения являются допустимыми кодировками символов. Я бы сказал, что использование строки для двоичных данных - это рецепт проблем.

Какая польза от строки? NSData - это именно тот тип данных, который вы хотите использовать для хранения двоичных данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...