Chuyển đổi NSData sang String?


122

Tôi đang lưu trữ Khóa riêng tư openssl EVP_PKEY dưới dạng nsdata. Đối với điều này, tôi đang tuần tự hóa thành một luồng byte bằng cách sử dụng mã bên dưới

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

trong đó pkey thuộc loại EVP_PKEY. Sau đó, tôi đang lưu trữ các byte từ bộ đệm 'p' dưới dạng NSData bằng cách sử dụng dòng dưới đây

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

Bây giờ tôi đang chuyển đổi nó thành một NSString bằng cách sử dụng mã được cung cấp bên dưới nhưng khi tôi in nó vào bảng điều khiển, nó sẽ đưa ra một số ký tự khác.

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

Ai đó có thể giúp đỡ?

Về cơ bản, tôi muốn lưu trữ EVP_PKEY vào cơ sở dữ liệu sqlite

có phải tôi đang trên đường ray bên phải không? Cảm ơn.


Ý bạn là gì, "một số ký tự khác"? Có phải nó đang in các ký tự thừa ở cuối không nên có, hay nó chỉ in các ký tự hoàn toàn khác với bạn mong đợi?
Tom Harrington

Nó hoàn toàn khác với những gì nó là phải
Zach

Bạn có chắc rằng dữ liệu thực sự được mã hóa UTF-8 không? Tôi không quen thuộc với i2d_PrivateKey nhưng kết quả của bạn cho thấy bạn không sử dụng mã hóa chuỗi phù hợp.
Tom Harrington

@TOm: Cảm ơn. đó là ASCIIEncoding. Bây giờ nó hoạt động tốt
Zach

Không, bạn đang không đi đúng hướng ở đây và tất cả các câu trả lời dường như không chính xác. Bạn nên sử dụng mã hóa base64 nếu bạn muốn chuyển đổi dữ liệu NSDatasang NSString.
Maarten Bodewes

Câu trả lời:


260

Objective-C

Bạn có thể sử dụng (xem Tham chiếu Lớp NSString )

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

Thí dụ:

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

Lưu ý : Vui lòng lưu ý NSDatagiá trị phải hợp lệ đối với mã hóa được chỉ định (UTF-8 trong ví dụ trên), nếu không nilsẽ được trả về:

Trả về nil nếu quá trình khởi tạo không thành công vì lý do nào đó (ví dụ: nếu dữ liệu không đại diện cho dữ liệu hợp lệ để mã hóa).

Trước Swift 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 trở đi

String(data: yourData, encoding: .utf8)

Xem Chuỗi # init (dữ liệu: mã hóa :) Tham khảo


Cảm ơn bạn đã trả lời. Tôi đã thử mà không thành công.
Zach

26
Trên trình gỡ lỗi:po [[NSString alloc] initWithData:myData encoding:4]
Berik

7
Làm thế nào câu trả lời này có thể có nhiều phiếu tán thành, mặc dù NSDatacó thể chứa bất kỳ giá trị byte nào, kể cả những giá trị nằm ngoài phạm vi UTF-8?
Maarten Bodewes

2
Bởi vì những người ở đây đang chuyển đổi phản hồi dữ liệu từ máy chủ thành một chuỗi.
Necro

1
điều gì sẽ xảy ra nếu NSData <strong> thực sự </strong> chứa các giá trị bên ngoài phạm vi UTF-8?
Zennichimaro

24

Trước Swift 3.0:

String(data: yourData, encoding: NSUTF8StringEncoding)

Đối với Swift 4.0:

String(data: yourData, encoding: .utf8)

3

Tôi tin rằng "P" của bạn là tham số dataWithBytes

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

nên là "buf"

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

vì i2d_PrivateKey đặt con trỏ đến bộ đệm đầu ra p ở cuối bộ đệm và chờ nhập thêm, và buf vẫn đang trỏ đến đầu bộ đệm của bạn.

Đoạn mã sau phù hợp với tôi trong đó pkey là con trỏ đến 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);

Bạn có thể sử dụng công cụ chuyển đổi trực tuyến để chuyển đổi dữ liệu nhị phân của mình thành cơ sở 64 ( http://tomeko.net/online_tools/hex_to_base64.php?lang=vi ) và so sánh nó với khóa riêng tư trong tệp cert của bạn sau khi sử dụng lệnh sau và kiểm tra đầu ra của mypkey.pem:

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

Tôi đã tham khảo câu hỏi của bạn và trang web chức năng EVP này cho câu trả lời của tôi.



1

Một cách đơn giản để chuyển đổi NSData tùy ý sang NSString là mã hóa base64.

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

Sau đó, bạn có thể lưu trữ nó vào cơ sở dữ liệu của mình để sử dụng lại sau này. Chỉ cần giải mã nó trở lại NSData.


1

Swift 5 :

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

Đây chỉ là một bản sao sửa đổi của câu trả lời Pierre23 tốt hơn cho tôi - Tôi thường sử dụng trang này để sao chép mã và phải sửa đổi Dữ liệu của bạn thành dữ liệu! điều đó cần có thời gian. Bây giờ tôi và bạn sao chép và dán mà không cần sửa đổi.
Alexander Volkov

Đây không phải là một câu hỏi liên quan đến Swift. Thêm nữa, mẫu mã trong câu hỏi là mã Objective-C. Và không phải cuối cùng việc mở khóa bắt buộc từ mã của bạn có thể dẫn đến sự cố không mong muốn.
Cristik

@Cristik Câu hỏi không được gắn thẻ là Obj-C.
Eiko

@AlexanderVolkov, bạn có thể thêm một đoạn mã Xcode cho điều đó, nó thậm chí còn nhanh hơn thế này;)
Cristik 22/08/2016
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.