(.NET の場合) byte[] (画像など)に任意のバイナリ データを格納しています。次に、そのデータを文字列(レガシー API の「コメント」フィールド)に格納する必要があります。このバイナリデータを文字列にパックするための標準的な手法はありますか? 「パッキング」とは、適度に大きくランダムなデータセットの場合、bytes.Length/2がpacked.Lengthとほぼ同じであることを意味します。2 バイトは多かれ少なかれ 1 文字であるためです。
2 つの「明白な」回答は、すべての基準を満たしていません。
string base64 = System.Convert.ToBase64String(bytes)
利用可能な約60,000文字のうち64文字しか使用しないため、文字列を非常に効率的に使用することはできません(私のストレージはSystem.Stringです)。一緒に行く
string utf16 = System.Text.Encoding.Unicode.GetString(bytes)
stringをより有効に活用できますが、無効な Unicode 文字 (サロゲート ペアの不一致など) を含むデータでは機能しません。 この MSDN の記事では、この正確な (貧弱な) 手法が示されています。
簡単な例を見てみましょう。
byte[] bytes = new byte[] { 0x41, 0x00, 0x31, 0x00};
string utf16 = System.Text.Encoding.Unicode.GetString(bytes);
byte[] utf16_bytes = System.Text.Encoding.Unicode.GetBytes(utf16);
この場合、元のバイトが UTF-16 文字列だったため、 bytesとutf16_bytesは同じです。これと同じ手順を base64 エンコーディングで実行すると、16 メンバーのbase64_bytes配列が得られます。
ここで、無効な UTF-16 データを使用して手順を繰り返します。
byte[] bytes = new byte[] { 0x41, 0x00, 0x00, 0xD8};
utf16_bytesが元のデータと一致しないことがわかります。
無効な Unicode 文字の前のエスケープとして U+FFFD を使用するコードを作成しました。それは機能しますが、自分で作ったものよりも標準的なテクニックがあるかどうか知りたい. 言うまでもなく、無効な文字を検出する方法としてDecoderFallbackExceptionをキャッチするのは好きではありません。
これを「ベース BMP」または「ベース UTF-16」エンコーディング (Unicode Basic Multilingual Plane のすべての文字を使用) と呼ぶことができると思います。はい、理想的には、Shawn Steele のアドバイスに従い、 byte[]を渡します。
Peter Housel の提案を「正しい」答えとして使用します。「標準的な手法」の提案に近づいたのは彼だけだからです。