Solución:
Aquí hay un pequeño programa de prueba que ilustra una diferencia en las cadenas codificadas:
byte[] bytes = new byte[57];
String enc1 = new sun.misc.BASE64Encoder().encode(bytes);
String enc2 = new String(java.util.Base64.getMimeEncoder().encode(bytes),
StandardCharsets.UTF_8);
System.out.println("enc1 = <" + enc1 + ">");
System.out.println("enc2 = <" + enc2 + ">");
System.out.println(enc1.equals(enc2));
Su salida es:
enc1 = <AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
>
enc2 = <AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>
false
Tenga en cuenta que la salida codificada de sun.misc.BASE64Encoder
tiene una nueva línea al final. No lo hace siempre agregar una nueva línea, pero sucede que lo hace si la cadena codificada tiene exactamente 76 caracteres en su última línea. (El autor de java.util.Base64
consideró que se trataba de un pequeño error en el sun.misc.BASE64Encoder
implementación – vea el hilo de revisión).
Esto puede parecer una trivialidad, pero si tuviera un programa que se basara en este comportamiento específico, cambiar los codificadores podría dar como resultado una salida con formato incorrecto. Por tanto, concluyo que java.util.Base64
es no un reemplazo directo para sun.misc.BASE64Encoder
.
Por supuesto, el intención de java.util.Base64
es que es un reemplazo funcionalmente equivalente, compatible con RFC, de alto rendimiento, totalmente compatible y especificado que está destinado a admitir la migración de código fuera de sun.misc.BASE64Encoder
. Sin embargo, debe tener en cuenta algunos casos extremos como este al migrar.
No hay cambios en la especificación base64 entre rfc1521 y rfc2045.
Todas las implementaciones de base64 podrían considerarse reemplazos directos entre sí, las únicas diferencias entre las implementaciones de base64 son:
- el alfabeto utilizado.
- las API proporcionadas (por ejemplo, algunas pueden actuar solo en un búfer de entrada completo, mientras que otras pueden ser máquinas de estado finito que le permiten continuar enviando trozos de entrada a través de ellas hasta que haya terminado).
El alfabeto MIME base64 se ha mantenido constante entre las versiones de RFC (se tiene o el software anterior se rompería) y es: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/
Como señala Wikipedia, solo los últimos 2 caracteres pueden cambiar entre las implementaciones de base64.
Como ejemplo de una implementación base64 que lo hace cambiar los 2 últimos caracteres, la especificación IMAP MUTF-7 utiliza el siguiente alfabeto base64: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+,
El motivo del cambio es que el /
El carácter se usa a menudo como un delimitador de ruta y, dado que la codificación MUTF-7 se usa para aplanar rutas de directorio no ASCII en ASCII, la /
era necesario evitar el carácter en los segmentos codificados.
Tuve el mismo problema, cuando me mudé de sun a java.util.base64, pero org.apache.commons.codec.binary.Base64 esto resolvió mi problema