将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数据库中

我在正确的轨道上吗?谢谢。


“其他字符”是什么意思?是在末尾打印多余的字符,还是只是打印出与预期完全不同的字符?
汤姆·哈灵顿

它与实际情况完全不同
Zach

您确定数据实际上是UTF-8编码的吗?我对i2d_PrivateKey不熟悉,但是您的结果表明您没有使用正确的字符串编码。
汤姆·哈灵顿

@汤姆:谢谢。这是ASCIIEncoding。现在工作正常
Zach

不,您的位置不正确,所有答案似乎都不正确。如果你想将数据转换中,你应该使用base64编码NSDataNSString
Maarten Bodewes 2013年

Answers:


260

目标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 :)参考


感谢您的答复。我已经尝试过,但没有成功。
Zach

26
在调试器上:po [[NSString alloc] initWithData:myData encoding:4]
Berik

7
即使答案NSData可能包含任何字节值(包括UTF-8范围之外的字节值),此答案也如何具有众多优势?
Maarten Bodewes

2
因为这里的人们正在将数据响应从服务器转换为字符串。
Necro 2013年

1
如果NSData <strong>确实</ strong>包含的值超出UTF-8范围怎么办?
Zennichimaro 2015年

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

您可以使用在线转换器将二进制数据转换为base 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答案的修改后的副本,对我来说更好-我通常使用此页面来复制代码,并且不得不将yourData修改为数据!这需要时间。现在,我和您无需修改​​即可复制和粘贴。
亚历山大·沃尔科夫

这不是Swift相关的问题。此外,问题中的代码示例是Objective-C代码。最后,强行将代码从代码中解包可能会导致意外崩溃。
Cristik '16

@Cristik该问题未被标记为Obj-C。
Eiko

@AlexanderVolkov,您可以为此添加一个Xcode代码段,它的速度甚至比这还快;)
Cristik 2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.