Ubah NSData ke String?

122

Saya menyimpan Kunci pribadi openssl EVP_PKEY sebagai nsdata. Untuk ini saya membuat serial menjadi aliran byte menggunakan kode di bawah ini

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

dengan pkey berjenis EVP_PKEY. Kemudian saya menyimpan byte dari buffer 'p' sebagai NSData menggunakan baris yang diberikan di bawah ini

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

Sekarang saya mengubahnya menjadi NSString menggunakan kode yang diberikan di bawah ini tetapi ketika saya mencetaknya ke konsol itu memberikan beberapa karakter lain.

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

Bisakah seseorang membantu?

Pada dasarnya saya ingin menyimpan EVP_PKEY ke dalam database sqlite

apakah saya di jalur yang benar? Terima kasih.

Zach
sumber
Apa maksud Anda, "beberapa karakter lain"? Apakah mencetak karakter ekstra di akhir yang seharusnya tidak ada, atau hanya mencetak karakter yang sama sekali berbeda dari yang Anda harapkan?
Tom Harrington
Ini benar-benar berbeda dari yang seharusnya
Zach
Apakah Anda yakin bahwa data sebenarnya dikodekan dengan UTF-8? Saya tidak terbiasa dengan i2d_PrivateKey tetapi hasil Anda menunjukkan Anda tidak menggunakan pengkodean string yang benar.
Tom Harrington
@TOm: Terima kasih. itu ASCIIEncoding. Sekarang berfungsi dengan baik
Zach
Tidak, Anda tidak berada di jalur yang benar di sini, dan semua jawaban tampaknya salah. Anda harus menggunakan pengkodean base64 jika Anda ingin mengonversi data NSDatamenjadi NSString.
Maarten Bodewes

Jawaban:

260

Objective-C

Anda dapat menggunakan (lihat Referensi Kelas NSString )

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

Contoh:

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

Catatan : Harap perhatikan bahwa NSDatanilainya harus valid untuk pengkodean yang ditentukan (UTF-8 dalam contoh di atas), jika tidak nilakan dikembalikan:

Menampilkan nil jika inisialisasi gagal karena beberapa alasan (misalnya jika data tidak mewakili data yang valid untuk encoding).

Sebelumnya Swift 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 dan Selanjutnya

String(data: yourData, encoding: .utf8)

Lihat Referensi String # init (data: encoding :)

louiscoquio
sumber
Terima kasih atas balasan Anda. Saya sudah mencobanya tetapi tidak berhasil.
Zach
26
Di debugger:po [[NSString alloc] initWithData:myData encoding:4]
Berik
7
Bagaimana jawaban ini dapat memiliki banyak suara positif, meskipun NSDatamungkin berisi nilai byte apa pun, termasuk yang di luar kisaran UTF-8?
Maarten Bodewes
2
Karena orang-orang yang ada di sini mengonversi respons data dari server menjadi string.
Necro
1
bagaimana jika NSData <strong> memang </strong> berisi nilai di luar rentang UTF-8?
Zennichimaro
24

Swift 3.0 sebelumnya:

String(data: yourData, encoding: NSUTF8StringEncoding)

Untuk Swift 4.0:

String(data: yourData, encoding: .utf8)
pierre23
sumber
3

Saya percaya "P" Anda sebagai parameter dataWithBytes

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

harus "buf"

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

karena i2d_PrivateKey meletakkan pointer ke buffer keluaran p di akhir buffer dan menunggu masukan lebih lanjut, dan buf masih menunjuk ke awal buffer Anda.

Kode berikut berfungsi untuk saya di mana pkey adalah penunjuk ke 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);

Anda dapat menggunakan konverter online untuk mengubah data biner Anda menjadi basis 64 ( http://tomeko.net/online_tools/hex_to_base64.php?lang=en ) dan membandingkannya dengan kunci privat di file cert Anda setelah menggunakan perintah berikut dan memeriksa output mypkey.pem:

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

Saya mereferensikan pertanyaan Anda dan situs fungsi EVP ini untuk jawaban saya.

aspergillusOryzae
sumber
2

Cepat 3:

String(data: data, encoding: .utf8)
Travis M.
sumber
1

Cara sederhana untuk mengonversi NSData arbitrer ke NSString adalah dengan menyandikannya base64.

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

Anda kemudian dapat menyimpannya ke dalam database Anda untuk digunakan kembali nanti. Cukup decode kembali ke NSData.

Billy
sumber
1

Cepat 5 :

String(data: data!, encoding: String.Encoding.utf8)
Alexander Volkov
sumber
Ini hanya salinan jawaban pierre23 yang dimodifikasi yang lebih baik bagi saya - Saya biasanya menggunakan halaman ini untuk menyalin kode dan harus memodifikasi dataAnda menjadi data! itu membutuhkan waktu. Sekarang saya dan Anda menyalin dan menempel tanpa modifikasi.
Alexander Volkov
Ini bukan pertanyaan terkait Swift. Lebih lanjut, contoh kode dalam pertanyaan adalah kode Objective-C. Dan bukan terakhir, pembongkaran paksa dari kode Anda dapat menyebabkan crash yang tidak terduga.
Cristik
@Cristik Pertanyaannya tidak di-tag sebagai Obj-C.
Eiko
@AlexanderVolkov Anda dapat menambahkan potongan Xcode untuk itu, itu akan lebih cepat dari ini;)
Cristik