แปลง 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

ฉันมาถูกทางหรือเปล่า ขอบคุณ


คุณหมายถึงอะไร "อักขระอื่น ๆ "? มีการพิมพ์อักขระพิเศษในตอนท้ายที่ไม่ควรมีหรือเพียงแค่พิมพ์อักขระที่แตกต่างไปจากที่คุณคาดไว้?
Tom Harrington

มันแตกต่างอย่างสิ้นเชิงกับสิ่งที่เป็นอยู่
Zach

แน่ใจหรือว่าข้อมูลนั้นเข้ารหัส 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 หากการเริ่มต้นล้มเหลวด้วยเหตุผลบางประการ (ตัวอย่างเช่นหากข้อมูลไม่ได้แสดงถึงข้อมูลที่ถูกต้องสำหรับการเข้ารหัส)

ก่อนหน้า Swift 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 เป็นต้นไป

String(data: yourData, encoding: .utf8)

ดูString # init (data: encoding :) Reference


ขอบคุณสำหรับการตอบกลับฉันได้ลองแล้ว แต่ไม่ประสบความสำเร็จ
Zach

26
เกี่ยวกับดีบักเกอร์:po [[NSString alloc] initWithData:myData encoding:4]
Berik

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];

ควรเป็น "buf"

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

สวิฟต์ 5 :

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

นี่เป็นเพียงสำเนาคำตอบ pierre23 ที่แก้ไขแล้วซึ่งดีกว่าสำหรับฉัน - โดยปกติฉันจะใช้หน้านี้เพื่อคัดลอกโค้ดและต้องแก้ไขข้อมูลของคุณเป็นข้อมูล! ที่ต้องใช้เวลา ตอนนี้ฉันและคุณคัดลอกและวางโดยไม่มีการแก้ไข
Alexander Volkov

นี่ไม่ใช่คำถามที่เกี่ยวข้องกับ Swift เพิ่มเติมตัวอย่างโค้ดในคำถามคือรหัส Objective-C และสุดท้ายการบังคับแกะโค้ดของคุณอาจทำให้เกิดข้อขัดข้องโดยไม่คาดคิดได้
Cristik

@ คริสติกคำถามไม่ได้แท็กเป็น Obj-C
Eiko

@AlexanderVolkov คุณสามารถเพิ่มข้อมูลโค้ด Xcode เพื่อที่มันจะเร็วกว่านี้อีก;)
Cristik
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.