1. Información general
En este tutorial, exploramos las diversas utilidades que brindan la funcionalidad de codificación y decodificación Base64 en Java.
Principalmente vamos a ilustrar las nuevas API de Java 8 y las API de utilidades que están saliendo de Apache Commons.
2. Java 8 para Base 64
Java 8 finalmente ha agregado capacidades Base64 a la API estándar. Esto es a través de la clase de utilidad java.util.Base64 .
Comencemos por mirar un proceso de codificador básico.
2.1. Java 8 Basic Base64
El codificador básico simplifica las cosas y codifica la entrada como está, sin ninguna separación de línea.
La salida se asigna a un conjunto de caracteres en el conjunto de caracteres A-Za-z0-9 + / , y el decodificador rechaza cualquier carácter fuera de este conjunto.
Primero codifiquemos una cadena simple :
String originalInput = "test input"; String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes());
Observe cómo recuperamos la API de codificador completa a través del método de utilidad getEncoder () simple .
Decodifiquemos ahora ese String a la forma original:
byte[] decodedBytes = Base64.getDecoder().decode(encodedString); String decodedString = new String(decodedBytes);
2.2. Codificación Java 8 Base64 sin relleno
En la codificación Base64, la longitud de la cadena con codificación de salida debe ser múltiplo de tres. De lo contrario, la salida se rellenará con caracteres adicionales ( = ).
Tras la decodificación, estos caracteres de relleno adicionales se descartarán. Para profundizar en el relleno en Base64, consulte esta respuesta detallada en Stack Overflow.
Si necesitamos omitir el relleno de la salida , tal vez porque la cadena resultante nunca se volverá a decodificar, simplemente podemos elegir codificar sin relleno :
String encodedString = Base64.getEncoder().withoutPadding().encodeToString(originalInput.getBytes());
2.3. Codificación de URL de Java 8
La codificación de URL es muy similar al codificador básico que vimos anteriormente. Utiliza el alfabeto de URL y nombre de archivo Safe Base64 y no agrega ninguna separación de línea:
String originalUrl = "//www.google.co.nz/?gfe_rd=cr&ei=dzbFV&gws_rd=ssl#q=java"; String encodedUrl = Base64.getUrlEncoder().encodeToString(originalURL.getBytes());
La decodificación ocurre de la misma manera. El método de la utilidad getUrlDecoder () devuelve un java.util.Base64.Decoder que luego se usa para decodificar la URL:
byte[] decodedBytes = Base64.getUrlDecoder().decode(encodedUrl); String decodedUrl = new String(decodedBytes);
2.4. Codificación MIME de Java 8
Comencemos generando alguna entrada MIME básica para codificar:
private static StringBuilder getMimeBuffer() { StringBuilder buffer = new StringBuilder(); for (int count = 0; count < 10; ++count) { buffer.append(UUID.randomUUID().toString()); } return buffer; }
El codificador MIME genera una salida codificada en Base64 utilizando el alfabeto básico pero en un formato compatible con MIME.
Cada línea de la salida no tiene más de 76 caracteres y termina con un retorno de carro seguido de un salto de línea ( \ r \ n ):
StringBuilder buffer = getMimeBuffer(); byte[] encodedAsBytes = buffer.toString().getBytes(); String encodedMime = Base64.getMimeEncoder().encodeToString(encodedAsBytes);
El método de la utilidad getMimeDecoder () devuelve un java.util.Base64.Decoder que luego se usa en el proceso de decodificación:
byte[] decodedBytes = Base64.getMimeDecoder().decode(encodedMime); String decodedMime = new String(decodedBytes);
3. Codificación / decodificación mediante código Apache Commons
Primero, necesitamos definir la dependencia commons-codec en pom.xml :
commons-codec commons-codec 1.10
Tenga en cuenta que podemos verificar si se han lanzado versiones más nuevas de la biblioteca en Maven Central.
La API principal es la clase org.apache.commons.codec.binary.Base64 , que se puede parametrizar con varios constructores:
- Base64 (boolean urlSafe) crea la API Base64 controlando el modo seguro de URL, activado o desactivado.
- Base64 (int lineLength) crea la API Base64 en un modo inseguro de URL y controla la longitud de la línea (el valor predeterminado es 76).
- Base64 (int lineLength, byte [] lineSeparator) crea la API Base64 aceptando un separador de línea adicional, que por defecto es CRLF (“\ r \ n”).
Una vez que se crea la API Base64, tanto la codificación como la decodificación son bastante simples:
String originalInput = "test input"; Base64 base64 = new Base64(); String encodedString = new String(base64.encode(originalInput.getBytes()));
El método decode () de la clase Base64 devuelve la cadena decodificada:
String decodedString = new String(base64.decode(encodedString.getBytes()));
Otra opción simple es usar la API estática de Base64 en lugar de crear una instancia:
String originalInput = "test input"; String encodedString = new String(Base64.encodeBase64(originalInput.getBytes())); String decodedString = new String(Base64.decodeBase64(encodedString.getBytes()));
4. Conversión de una cadena en una matriz de bytes
A veces, necesitamos convertir una cadena en un byte [] . La forma más sencilla de hacer esto es usar el método String getBytes () :
String originalInput = "test input"; byte[] result = originalInput.getBytes(); assertEquals(originalInput.length(), result.length);
It's better to provide encoding as well and not depend on default encoding, as it's system dependent:
String originalInput = "test input"; byte[] result = originalInput.getBytes(StandardCharsets.UTF_16); assertTrue(originalInput.length() < result.length);
If our String is Base64 encoded, we can use the Base64 decoder:
String originalInput = "dGVzdCBpbnB1dA=="; byte[] result = Base64.getDecoder().decode(originalInput); assertEquals("test input", new String(result));
We can also use DatatypeConverter parseBase64Binary() method:
String originalInput = "dGVzdCBpbnB1dA=="; byte[] result = DatatypeConverter.parseBase64Binary(originalInput); assertEquals("test input", new String(result));
Finally, we can convert a hexadecimal String to a byte[] using DatatypeConverter method:
String originalInput = "7465737420696E707574"; byte[] result = DatatypeConverter.parseHexBinary(originalInput); assertEquals("test input", new String(result));
5. Conclusion
This article explained the basics of how to do Base64 encoding and decoding in Java using the new APIs introduced in Java 8 and Apache Commons.
Finalmente, hay algunas otras API que vale la pena mencionar que brindan una funcionalidad similar: java.xml.bind.DataTypeConverter con printHexBinary y parseBase64Binary .
Los fragmentos de código se pueden encontrar en GitHub.