15

オブジェクトのシリアル化を試みており、Base64 で結果をエンコードしています。Sun の lib で動作します。

Bean01 bean01 = new Bean01();
bean01.setDefaultValues();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream( baos ).writeObject( bean01 );
System.out.println(Base64.encode(baos.toByteArray()));

これはうまくいきます。ただし、org.apache.commons.codec.binary.base64 を使用して同じことを行いたいのですが、これは同じ文字列を返しません。

System.out.println(org.apache.commons.codec.binary.Base64.encodeBase64(baos.toByteArray()));

Apache のエンコーダーを使用して byteArray の正しい Base64 エンコーディングを実現する正しい方法は何でしょうか?

4

2 に答える 2

25

実際、使用commons-codecているバージョンと特定の Sun 内部バージョンでは、同じ結果が得られます。暗黙的に配列を呼び出しているため、異なるバージョンを提供していると思ったと思います。toString()

System.out.println(org.apache.commons.codec.binary.Base64.encodeBase64(baos.toByteArray()));

これは間違いなく配列の内容を出力しません。代わりに、配列参照のアドレスのみが出力されます。

エンコーダーを相互にテストするために、次のプログラムを作成しました。以下の出力から、同じ結果が得られることがわかります。

import java.util.Random;

public class Base64Stuff
{
    public static void main(String[] args) {
        Random random = new Random();
        byte[] randomBytes = new byte[32];
        random.nextBytes(randomBytes);

        String internalVersion = com.sun.org.apache.xerces.internal.impl.dv.util.Base64.encode(randomBytes);
        byte[] apacheBytes =  org.apache.commons.codec.binary.Base64.encodeBase64(randomBytes);
        String fromApacheBytes = new String(apacheBytes);

        System.out.println("Internal length = " + internalVersion.length());
        System.out.println("Apache bytes len= " + fromApacheBytes.length());
        System.out.println("Internal version = |" + internalVersion + "|");
        System.out.println("Apache bytes     = |" + fromApacheBytes + "|");
        System.out.println("internal equal apache bytes?: " + internalVersion.equals(fromApacheBytes));
    }
}

そして、これを実行した結果が次のとおりです。

Internal length = 44
Apache bytes len= 44
Internal version = |Kf0JBpbxCfXutxjveYs8CXMsFpQYgkllcHHzJJsz9+g=|
Apache bytes     = |Kf0JBpbxCfXutxjveYs8CXMsFpQYgkllcHHzJJsz9+g=|
internal equal apache bytes?: true
于 2012-05-25T01:11:20.287 に答える
2

commons-codec ホームページから:

Codec は、Base64 エンコーダーの 1 つの決定的な実装に開発努力を集中させる試みとして形成されました。Codec の提案の時点で、Foundation の CVS リポジトリに広がる Base64 エンコーディングを扱う約 34 の異なる Java クラスがありました。Jakarta Tomcat プロジェクトの開発者は、Commons HttpClient および Apache XML プロジェクトの XML-RPC サブプロジェクトによってコピーされた Base64 コーデックのオリジナル バージョンを実装していました。ほぼ 1 年後、分岐した Base64 の 2 つのバージョンは、互いに大きく異なっていました。XML-RPC は、Commons HttpClient Base64 には適用されなかった多くの修正とパッチを適用しました。サブプロジェクトが異なれば、RFC 2045 への準拠のさまざまなレベルで実装も異なります。

あなたの問題は、コンプライアンスの「さまざまなレベル」だと思います。

私のアドバイス: 1 つの base64 エンコーダー/デコーダーを選択し、それに固執します。

于 2012-05-24T20:38:15.100 に答える