Преобразовать NSData в строку?


122

Я храню закрытый ключ openssl EVP_PKEY как nsdata. Для этого я сериализую в поток байтов, используя приведенный ниже код.

unsigned char *buf, *p;
int len;
len = i2d_PrivateKey(pkey, NULL);
buf = OPENSSL_malloc(len); 
p = buf;
i2d_PrivateKey(pkey, &p);

где pkey имеет тип EVP_PKEY. Затем я сохраняю байты из буфера 'p' как NSData, используя строку, приведенную ниже

NSData *keydata = [NSData dataWithBytes:P length:len];

Теперь я конвертирую его в NSString, используя приведенный ниже код, но когда я печатаю его на консоли, он дает некоторые другие символы.

NSString *content =[ NSString stringWithCString:[keydata bytes] encoding:NSUTF8StringEncoding];

Может кто-нибудь помочь?

В основном я хочу сохранить EVP_PKEY в базе данных sqlite

я на правильном пути? Спасибо.


Что значит «другие персонажи»? В конце печатаются лишние символы, которых не должно быть, или просто печатаются совершенно другие символы, чем вы ожидаете?
Tom Harrington

Это полностью отличается от того, чем оно должно быть,
Зак

Вы уверены, что данные действительно закодированы в UTF-8? Я не знаком с i2d_PrivateKey, но ваши результаты показывают, что вы не используете правильную кодировку строк.
Tom Harrington

@TOm: Спасибо. это было ASCIIEncoding. Теперь он работает нормально
Zach

Нет, вы здесь не на правильном пути, и все ответы кажутся неверными. Вы должны использовать кодировку base64, если хотите преобразовать данные в NSDataформат NSString.
Maarten Bodewes

Ответы:


260

Objective-C

Вы можете использовать (см. Справочник по классам NSString )

- (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding

Пример:

NSString *myString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];

Примечание : обратите внимание, что NSDataзначение должно быть действительным для указанной кодировки (UTF-8 в приведенном выше примере), в противном случае nilбудет возвращено:

Возвращает nil, если инициализация не удалась по какой-либо причине (например, если данные не представляют допустимые данные для кодирования).

Приор Свифт 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 и выше

String(data: yourData, encoding: .utf8)

См. String # init (data: encoding :) Ссылка


Спасибо за ответ. Я уже пробовал это безуспешно.
Zach

26
О отладчике:po [[NSString alloc] initWithData:myData encoding:4]
Берик

7
Как этот ответ может иметь множество положительных отзывов, даже если он NSDataможет содержать любое байтовое значение, в том числе вне диапазона UTF-8?
Maarten Bodewes

2
Потому что люди, которые здесь, преобразуют ответ данных с сервера в строку.
Necro

1
что, если NSData <strong> действительно </strong> содержит значения вне диапазона UTF-8?
Зенничимаро

24

Предыдущий Swift 3.0:

String(data: yourData, encoding: NSUTF8StringEncoding)

Для Swift 4.0:

String(data: yourData, encoding: .utf8)

3

Я считаю, что ваш "P" как параметр dataWithBytes

NSData *keydata = [NSData dataWithBytes:P length:len];

должно быть "буф"

NSData *keydata = [NSData dataWithBytes:buf length:len];

поскольку i2d_PrivateKey помещает указатель на выходной буфер p в конец буфера и ожидает дальнейшего ввода, а buf все еще указывает на начало вашего буфера.

Для меня работает следующий код, где pkey - указатель на EVP_PKEY:

unsigned char *buf, *pp;
int len = i2d_PrivateKey(pkey, NULL);
buf = OPENSSL_malloc(len); 
pp = buf;
i2d_PrivateKey(pkey, &pp);

NSData* pkeyData = [NSData dataWithBytes:(const void *)buf length:len];
DLog(@"Private key in hex (%d): %@", len, pkeyData);

Вы можете использовать онлайн-конвертер для преобразования ваших двоичных данных в базу 64 ( http://tomeko.net/online_tools/hex_to_base64.php?lang=en ) и сравнить их с закрытым ключом в вашем файле сертификата после использования следующей команды и проверка вывода mypkey.pem:

openssl pkcs12 -in myCert.p12 -nocerts -nodes -out mypkey.pem

Я сослался на ваш вопрос и этот сайт функции EVP для своего ответа.



1

Простой способ преобразовать произвольные NSData в NSString - это закодировать их в формате base64.

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

Затем вы можете сохранить его в своей базе данных для повторного использования позже. Просто декодируйте его обратно в NSData.


1

Swift 5 :

String(data: data!, encoding: String.Encoding.utf8)

Это просто измененная копия ответа pierre23, которая мне больше подходит - я обычно использовал эту страницу для копирования кода и мне приходилось изменять yourData на data! это требует времени. Теперь мы с вами копируем и вставляем без изменений.
Александр Волков

Это не вопрос, связанный с Swift. Более того, образец кода в вопросе - это код Objective-C. И не в последнюю очередь принудительное развертывание кода из вашего кода может привести к неожиданным сбоям.
Cristik

@Cristik Вопрос не помечен как Obj-C.
Eiko

@AlexanderVolkov, вы можете добавить для этого фрагмент Xcode, это было бы даже быстрее, чем этот;)
Cristik
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.