NSDataを文字列に変換しますか?


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に精通していませんが、正しい文字列エンコーディングを使用していないことが結果からわかります。
トムハリントン

@TOm:ありがとう。それはASCIIEncodingでした。今では正常に動作しています
Zach

いいえ、あなたはここで正しい軌道に乗っていません。すべての答えは正しくないようです。あなたがデータを変換したい場合は、base64エンコードを使用する必要がありますNSDataしますNSString
Maarten Bodewes 2013

回答:


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)

参照文字列#1のinit(データ:エンコード:)リファレンス


お返事ありがとうございます。私はすでに成功していません。
Zach

26
デバッガー:po [[NSString alloc] initWithData:myData encoding:4]
Berik

7
NSDataUTF-8の範囲外のバイト値を含むバイト値が含まれている場合でも、この回答にはどのようにして多数の投票がありますか?
Maarten Bodewes 2013

2
ここにいる人々はサーバーからのデータ応答を文字列に変換しているからです。
ネクロ

1
NSDataがUTF-8の範囲外の値を<strong>確かに</ strong>含む場合はどうなりますか?
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];

「バフ」である必要があります

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)に変換し、次のコマンドを使用した後、それを証明書ファイルの秘密キーと比較できます。 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をデータに変更する必要がありました。それには時間がかかります。今、私とあなたは修正なしでコピーして貼り付けます。
Alexander Volkov

これはSwift関連の質問ではありません。さらに、問題のコードサンプルはObjective-Cコードです。最後に、コードからの強制アンラップが予期しないクラッシュにつながる可能性はありません。
Cristik

@Cristik質問はObj-Cとしてタグ付けされていません。
Eiko

@AlexanderVolkovにはXcodeスニペットを追加できます。これよりもさらに高速になります;)
Cristik
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.