Как Base64 кодирует объект Java, используя org.apache.commons.codec.binary.base64?

Я пытаюсь выполнить сериализацию объекта, а 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()));

Каким будет правильный способ для получения правильной кодировки Base64 байтаArray с использованием кодера Apache?

Ответ 1

Фактически версия commons-codec и конкретная внутренняя версия Sun, используемая do, дают те же результаты. Я думаю, вы думали, что они дают разные версии, потому что вы неявно вызываете 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

Ответ 2

От домашняя страница commons-codec:

Кодек был создан как попытка сосредоточить усилия на окончательная реализация кодировщика Base64. В момент Codec, было около 34 различных классов Java, которые касаются кодирования Base64, распространяемого по Foundation CVS репозиторий. Разработчики проекта Jakarta Tomcat оригинальная версия кодека Base64, которая была скопирована Commons HttpClient и Apache XML-проект XML-RPC подпроект. После почти один год, две разветвленные версии Base64 значительно расходились друг от друга. XML-RPC применил многочисленные исправления и исправления, которые не были применены к базе данных HttpClient Base64. Различные подпроекты имели разные реализации на разных уровнях соответствия RFC 2045.

Я думаю, что ваша проблема - это "различный уровень" соответствия.

Мой совет: выберите один кодер/декодер base64 и придерживайтесь его