Перетворити NSData в String?


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

я на правильному шляху? Дякую.


Що ви маєте на увазі "деякі інші персонажі"? Це друк зайвих символів у кінці, яких там не повинно бути, чи це просто друк зовсім інших символів, ніж ви очікували?
Том Харрінгтон

Це зовсім інше, ніж воно має бути
Зак

Ви впевнені, що дані насправді закодовані UTF-8? Я не знайомий з i2d_PrivateKey, але результати показують, що ви не використовуєте правильне кодування рядків.
Том Харрінгтон

@TOm: Дякую це було ASCIIEncoding. Зараз його нормально працює
Зак

Ні, ви не на правильному шляху тут, і всі відповіді здаються невірними. Ви повинні використовувати кодування base64 , якщо ви хочете , щоб перетворити дані в NSDataдо NSString.
Maarten Bodewes

Відповіді:


260

Ціль-С

Ви можете використовувати (див. Довідку про клас NSString )

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

Приклад:

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

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

Повертає нуль, якщо ініціалізація з якоїсь причини не вдається (наприклад, якщо дані не представляють дійсних даних для кодування).

Попередній Swift 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Швидко натисніть 3.0

String(data: yourData, encoding: .utf8)

Див. Рядок # init (дані: кодування :) Довідка


Дякую за вашу відповідь. Я вже це намагався успішно.
Зак

26
На відладчику:po [[NSString alloc] initWithData:myData encoding:4]
Берік

7
Як ця відповідь може мати численні оновлення, хоча вони NSDataможуть містити будь-яке байтне значення, в тому числі й поза діапазоном UTF-8?
Maarten Bodewes

2
Тому що люди, які тут, перетворюють відповідь даних із сервера на рядок.
Necro

1
що робити, якщо NSData <strong> дійсно </strong> містять значення поза межами діапазону UTF-8?
Zennichimaro

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 ) та порівняти їх із приватним ключем у вашому файлі cert після використання наступної команди та перевірка виходу mypkey.pem:

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

Я посилався на ваше запитання і на цей сайт функцій EVP для своєї відповіді.



1

Простий спосіб перетворення довільної NSData в NSString - це кодування її base64.

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

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


1

Швидкий 5 :

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

Це просто модифікована копія відповіді pierre23, яка краще для мене - я зазвичай використовував цю сторінку, щоб скопіювати код, і мені довелося змінювати ваші дані на дані! на це потрібен час. Тепер ми з вами копіюємо та вставляємо без змін.
Олександр Волков

Це не пов'язане зі швидким питанням. Більше того, зразок коду у питанні - це об'єктивний-C код. І, нарешті, примусове видалення коду може призвести до несподіваних збоїв.
Крістік

@Cristik Питання не позначене як Obj-C.
Ейко

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