6

Java(Android)および.NET(Visual Basic)でテキストをBase64文字列に変換するのに問題があります。プレーン(読み取り可能)形式のASCII文字は正常に変換されます。しかし、特殊文字(コードが128より大きい文字)に関しては、それらは私にとって問題を引き起こしています。

たとえば、ASCII値が65の文字コード(文字「A」)を変換してみます。

私のJavaコードは次のとおりです。

char a = 65;
String c = String.valueOf(a); 
byte bt[] = c.getBytes();               
String result = Base64.encodeToString(bt, Base64.DEFAULT);

そして私の.NETコードは次のとおりです。

Dim c As String = Chr(65)
Dim result as String = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(c))

これらは両方とも同じ結果を返します: "QQ=="。これで結構です。しかし、特殊文字、たとえば文字コード153を変換しようとすると、異なる結果が返されます。

char a = 153;
String c = String.valueOf(a);               
byte bt[] = c.getBytes();               
String result = Base64.encodeToString(bt, Base64.DEFAULT);

これは「wpk="」を返します

そして私の同じ.NETコード:

Dim c As String = Chr(153) 
Dim result as String = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(c))

これは「4oSi」を返します

これはとても奇妙です。ここで何が問題なのですか。両方のプラットフォームでネイティブのBase64ライブラリを使用しています。私のコードに何か問題がありますか?

4

1 に答える 1

11

エンコードするデータは暗号化されたデータ(任意のバイトが0〜255であり、暗号化された状態では文字やテキストの意味がないランダムデータ)であるため、この情報をtrue binaryデータとして扱う必要があります。Javaと.NETはどちらも、それぞれのバイト配列プリミティブを介して真のバイナリデータを完全にサポートしています。

ご存知のように、base64エンコーディングは、真のバイナリデータ(0〜255の範囲)をわずかに大きいバイナリデータの配列に変換するプロセスです(各バイトは、32の間のASCII印刷可能文字と同じ値を持つことが保証されています)。および126)。これを呼びましょうencoded binary。事実上すべての既知のencoded binary文字セットが印刷可能なASCII文字セット(32から126)に同意するため、は安全にテキストに変換できます。

したがって、JavaスニペットとVB.NETスニペットの両方の主な問題は、テキストプリミティブ(JavaではcharとString)を使用しようとしていることです。データを格納するためのVB.NETの文字列true binary。それをしたら手遅れです。テキストプリミティブはバイナリデータを安全に格納および取得するように設計されていないため、バイト配列に確実に変換する方法はありません。これがなぜそうなのかについての詳細は、すべてのソフトウェア開発者が絶対に、Unicodeと文字セットについて絶対に知っておく必要がある絶対最小値を読んでください(言い訳はありません!)

幸い、修正は簡単です。Javaの場合、バイナリデータを格納するためにcharとStringを使用しないでください。データを直接バイト配列に入れます。次のことを試してください。

  byte [] bt = new byte[1];
  bt[0] = (byte) 153;
  String result = Base64.encodeToString(bt, Base64.DEFAULT);

mQ==を取得します

修正は、VB.NETでも概念的に同じです。文字列は使用しないでください。バイト配列を使用します。

    Dim bytes() As Byte = New Byte() {153}
    Dim result As String = Convert.ToBase64String(bytes)

繰り返しますが、答えはmQ==です。

最後に、エンコード後、文字列を使用することはまったく問題ありません。文字はASCIIサブセットにあり、すべての文字セットがASCIIサブセットに同意するため、文字列とバイト配列の間の変換によってデータが破損することはありません。

同じ問題が逆の順序で発生することを忘れないでください-デコード。バイト配列にデコードし、その時点でに戻りますtrue binary。この時点から、データを文字列として保存してはなりません-終了するまで-例:元のクリアテキストに復号化して戻します。

お役に立てれば。

于 2012-10-22T19:01:45.617 に答える