ChatGPT解决这个技术问题 Extra ChatGPT

Convert NSData to String?

I am storing a openssl private Key EVP_PKEY as nsdata. For this I am serializing into a byte stream using the code below

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

where pkey is of type EVP_PKEY. Then I am storing the bytes from buffer 'p' as an NSData using the line given below

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

Now I am converting it to a NSString using the code given below but when i print it into console its giving some other characters.

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

Could someone help?

Basically I want to store the EVP_PKEY into a sqlite database

am I on the right track? Thanks.

What do you mean, "some other characters"? Is it printing extra characters at the end that shouldn't be there, or is it just printing completely different characters than you expect?
Its completely different from what it is to be
Are you sure that the data is actually UTF-8 encoded? I'm not familiar with i2d_PrivateKey but your results suggest you're not using the right string encoding.
@TOm: Thanks. it was ASCIIEncoding. Now its working fine
No, you are not on the right track here, and all the answers seem incorrect. You should use base64 encoding if you want to convert the data in NSData to NSString.

M
Max MacLeod

Objective-C

You can use (see NSString Class Reference)

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

Example:

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

Remark: Please notice the NSData value must be valid for the encoding specified (UTF-8 in the example above), otherwise nil will be returned:

Returns nil if the initialization fails for some reason (for example if data does not represent valid data for encoding).

Prior Swift 3.0

String(data: yourData, encoding: NSUTF8StringEncoding)

Swift 3.0 Onwards

String(data: yourData, encoding: .utf8)

See String#init(data:encoding:) Reference


Thanks for your reply.I have already tried that with no success.
On the debugger: po [[NSString alloc] initWithData:myData encoding:4]
How can this answer have numerous upvotes, even though the NSData may contain any byte value, including those outside the UTF-8 range?
Because the people that are here are converting a data response from a server to a string.
what if NSData indeed contain values outside of UTF-8 range?
P
PinkeshGjr

Prior Swift 3.0 :

String(data: yourData, encoding: NSUTF8StringEncoding)

For Swift 4.0:

String(data: yourData, encoding: .utf8)

M
Maarten Bodewes

I believe your "P" as the dataWithBytes param

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

should be "buf"

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

since i2d_PrivateKey puts the pointer to the output buffer p at the end of the buffer and waiting for further input, and buf is still pointing to the beginning of your buffer.

The following code works for me where pkey is a pointer to an 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);

You can use an online converter to convert your binary data into base 64 (http://tomeko.net/online_tools/hex_to_base64.php?lang=en) and compare it to the private key in your cert file after using the following command and checking the output of mypkey.pem:

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

I referenced your question and this EVP function site for my answer.


A
Alexander Volkov

Swift 5:

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

This just a modified copy of pierre23 answer that is better for me - I usually used this page to copy the code and had to modify yourData to data! that takes time. Now I and you copy and paste without a modification.
This is not a Swift related question. More, the code sample in the question is Objective-C code. And not lastly the forced unwrap from your code can lead to unexpected crashes.
@Cristik The question is not tagged as Obj-C.
@AlexanderVolkov you can add an Xcode snippet for that, it would be even faster than this ;)
T
Travis M.

Swift 3:

String(data: data, encoding: .utf8)

B
Billy

A simple way to convert arbitrary NSData to NSString is to base64 encode it.

NSString *base64EncodedKey = [keydata base64EncodedStringWithOptions: NSDataBase64Encoding64CharacterLineLength];

You can then store it into your database for reuse later. Just decode it back to NSData.