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

Я храню закрытый ключ 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

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


person Zach    schedule 21.06.2011    source источник
comment
Что значит другие персонажи? В конце печатаются лишние символы, которых не должно быть, или просто печатаются совершенно другие символы, чем вы ожидаете?   -  person Tom Harrington    schedule 21.06.2011
comment
Это полностью отличается от того, что должно быть   -  person Zach    schedule 22.06.2011
comment
Вы уверены, что данные действительно закодированы в UTF-8? Я не знаком с i2d_PrivateKey, но ваши результаты показывают, что вы не используете правильную кодировку строк.   -  person Tom Harrington    schedule 22.06.2011
comment
@TOm: Спасибо. это было ASCIIEncoding. Теперь все работает нормально   -  person Zach    schedule 24.06.2011
comment
Нет, вы здесь не на правильном пути, и все ответы кажутся неверными. Вы должны использовать кодировку base64, если хотите преобразовать данные из NSData в NSString.   -  person Maarten Bodewes    schedule 06.08.2013


Ответы (6)


Цель-C

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

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

Пример:

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

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

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

Предыдущая версия Swift 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 и более поздних версий

String(data: yourData, encoding: .utf8)

См. String # init (data: encoding :) Справочник

person louiscoquio    schedule 21.06.2011
comment
Спасибо за ответ. Я уже пробовал это безуспешно. - person Zach; 21.06.2011
comment
@bshirley: Да, мы пробовали это .. все еще не работает .. не могли бы вы предложить мне способ сохранить мой evp_key в моей базе данных sqlite - person Zach; 21.06.2011
comment
В отладчике: po [[NSString alloc] initWithData:myData encoding:4] - person Berik; 01.11.2012
comment
Как этот ответ может иметь множество положительных отзывов, даже если NSData может содержать любое байтовое значение, в том числе вне диапазона UTF-8? - person Maarten Bodewes; 06.08.2013
comment
Потому что люди, которые здесь, преобразуют ответ данных с сервера в строку. - person Necro; 21.11.2013
comment
@owlstead Я обновил свой ответ. Теперь читатели знают, что значение NSData должно быть действительным для указанной кодировки. Спасибо! - person louiscoquio; 21.11.2013
comment
что, если NSData ‹strong› действительно ‹/strong› содержит значения вне диапазона UTF-8? - person Zennichimaro; 06.02.2015
comment
По документации будет возвращено nil. Я обновил свой ответ соответственно - person louiscoquio; 06.02.2015
comment
Есть ли удобный способ справиться с NSData, которые в основном являются строковыми данными, но не полностью? Я пытаюсь разработать методы, чтобы увидеть, что отправляется на сервер при отладке. У меня есть составные данные, включая изображение; Я не удивлен, что это не все допустимый UTF8, но я бы хотел видеть его с каким-то символом индикатора, например ∅, над этими байтами, чтобы я мог видеть подавляющее большинство данных, которые составляют допустимые символы. .. во-первых, все составные заголовки. - person Apollo Grace; 24.09.2016

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

String(data: yourData, encoding: NSUTF8StringEncoding)

Для Swift 4.0:

String(data: yourData, encoding: .utf8)
person pierre23    schedule 19.02.2016

Я считаю, что ваш "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.

person aspergillusOryzae    schedule 11.07.2012

Swift 3:

String(data: data, encoding: .utf8)
person Travis M.    schedule 17.10.2016

Swift 5:

String(data: data!, encoding: String.Encoding.utf8)
person Alexander Volkov    schedule 18.08.2016
comment
Это всего лишь модифицированная копия ответа pierre23, которая мне больше подходит - я обычно использовал эту страницу для копирования кода и мне приходилось изменять yourData на data! это требует времени. Теперь я и вы копируете и вставляете без изменений. - person Alexander Volkov; 18.08.2016
comment
Это не вопрос, связанный с Swift. Более того, образец кода в вопросе - это код Objective-C. И, наконец, принудительное развертывание кода из вашего кода может привести к неожиданным сбоям. - person Cristik; 18.08.2016
comment
@Cristik Вопрос не помечен как Obj-C. - person Eiko; 21.08.2016
comment
@AlexanderVolkov, вы можете добавить для этого фрагмент Xcode, это будет даже быстрее, чем это;) - person Cristik; 22.08.2016

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

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

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

person Billy    schedule 13.06.2018