Перетворити 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.