Codificação e decodificação Java Base64
1. Visão geral
Neste tutorial, vamos explorar os vários utilitários que fornecem codificação Base64 e funcionalidade de decodificação em Java.
Vamos principalmente ilustrar as novas APIs Java 8, bem como as APIs de utilitários que saem do Apache Commons.
Leitura adicional:
Guia para codificação / decodificação de URL Java
O artigo discute a codificação de URL em Java, algumas armadilhas e como evitá-las.
Novo armazenamento de senha no Spring Security 5
Um guia rápido para entender a criptografia de senha no Spring Security 5 e migrar para melhores algoritmos de criptografia.
2. Java 8 para Base 64
Java 8 has finally added Base64 capabilities para a API padrão, por meio dejava.util.Base64 utility class.
Vamos começar examinando um processo básico de codificação.
2.1. Java 8 Basic Base64
O codificador básico mantém as coisas simples e codifica a entrada como está - sem nenhuma separação de linha.
A saída é mapeada para um conjunto de caracteres no conjunto de caracteresA-Za-z0-9+/ e o decodificador rejeita qualquer caractere fora desse conjunto.
Vamos primeiroencode a simple String:
String originalInput = "test input";
String encodedString = Base64.getEncoder().encodeToString(originalInput.getBytes());
Observe como recuperamos a API Encoder completa por meio do método de utilitário simplesgetEncoder().
Vamos agora decodificar essa string de volta à forma original:
byte[] decodedBytes = Base64.getDecoder().decode(encodedString);
String decodedString = new String(decodedBytes);
2.2. Codificação Java 8 Base64 sem preenchimento
Na codificação Base64, o comprimento da String codificada de saída deve ser um múltiplo de 3. Se não for, a saída será preenchida com caracteres de preenchimento adicionais (=
).
Na decodificação, esses caracteres extras de preenchimento serão descartados. Para se aprofundar no preenchimento em Base64, verifiquethis detailed answer over on StackOverflow.
Se você precisarskip the padding of the output - talvez, porque a String resultante nunca será decodificada de volta - você pode simplesmente escolherencode without padding:
String encodedString =
Base64.getEncoder().withoutPadding().encodeToString(originalInput.getBytes());
2.3. Codificação de URL Java 8
A codificação de URL é muito semelhante ao codificador básico que vimos acima. Ele usa o alfabeto Base64 seguro de URL e nome de arquivo e não adiciona nenhuma separação de linha:
String originalUrl = "https://www.google.co.nz/?gfe_rd=cr&ei=dzbFV&gws_rd=ssl#q=java";
String encodedUrl = Base64.getUrlEncoder().encodeToString(originalURL.getBytes());
A decodificação acontece da mesma maneira - o método utilitáriogetUrlDecoder() retorna umjava.util.Base64.Decoder que é então usado para decodificar o URL:
byte[] decodedBytes = Base64.getUrlDecoder().decode(encodedUrl);
String decodedUrl = new String(decodedBytes);
2.4. Codificação Java 8 MIME
Vamos começar gerando alguma 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;
}
O codificador MIME gera uma saída codificada em Base64 usando o alfabeto básico, mas em um formato MIME amigável: cada linha da saída não tem mais que 76 caracteres e termina com um retorno de carro seguido por um avanço de linha ( ):
StringBuilder buffer = getMimeBuffer();
byte[] encodedAsBytes = buffer.toString().getBytes();
String encodedMime = Base64.getMimeEncoder().encodeToString(encodedAsBytes);
O método utilitáriogetMimeDecoder() retorna umjava.util.Base64.Decoder que é então usado no processo de decodificação:
byte[] decodedBytes = Base64.getMimeDecoder().decode(encodedMime);
String decodedMime = new String(decodedBytes);
3. Encoding/Decoding Using Apache Commons Code
Primeiro, precisamos definir a dependência commons-codec empom.xml:
commons-codec
commons-codec
1.10
Observe que você pode verificar se versões mais novas da biblioteca foram lançadas emMaven central.
A API principal é a classeorg.apache.commons.codec.binary.Base64 - que pode ser parametrizada com vários construtores:
-
Base64(boolean urlSafe) - cria a API Base64 controlando o modo de segurança de URL - ligado ou desligado
-
Base64 (int lineLength) - cria a API Base64 em um modo não seguro de URL e controlando o comprimento da linha (dpadrão é 76)
-
”)
Na API Base64 criada, a codificação e a decodificação são bastante simples:
String originalInput = "test input";
Base64 base64 = new Base64();
String encodedString = new String(base64.encode(originalInput.getBytes()));
O métododecode() da classeBase64 retorna a string decodificada:
String decodedString = new String(base64.decode(encodedString.getBytes()));
Outra opção simples éusing the static API of Base64 em vez de criar uma instância:
String originalInput = "test input";
String encodedString = new String(Base64.encodeBase64(originalInput.getBytes()));
String decodedString = new String(Base64.decodeBase64(encodedString.getBytes()));
4. Convertendo umString em um arraybyte
Às vezes, precisamos converter aString embyte[]. A maneira mais simples de fazer isso é usando o métodoStringgetBytes():
String originalInput = "test input";
byte[] result = originalInput.getBytes();
assertEquals(originalInput.length(), result.length);
É melhor fornecer codificação também e não depender da codificação padrão, pois depende do sistema:
String originalInput = "test input";
byte[] result = originalInput.getBytes(StandardCharsets.UTF_16);
assertTrue(originalInput.length() < result.length);
Se nossa String for codificada emBase64, podemos usar o decodificadorthe Base64:
String originalInput = "dGVzdCBpbnB1dA==";
byte[] result = Base64.getDecoder().decode(originalInput);
assertEquals("test input", new String(result));
Também podemos usar o métodoDatatypeConverter parseBase64Binary():
String originalInput = "dGVzdCBpbnB1dA==";
byte[] result = DatatypeConverter.parseBase64Binary(originalInput);
assertEquals("test input", new String(result));
Finalmente, podemos converter um hexadecimalString em umbyte[] usando o métodoDatatypeConverter:
String originalInput = "7465737420696E707574";
byte[] result = DatatypeConverter.parseHexBinary(originalInput);
assertEquals("test input", new String(result));
5. Conclusão
Este artigo explica os conceitos básicos de como codificar e decodificar Base64 em Java, usando as novas APIs introduzidas no Java 8 e no Apache Commons.
Finalmente, existem algumas outras APIs que valem a pena mencionar por fornecer funcionalidade semelhante - por exemplojava.xml.bind.DataTypeConverter comprintHexBinaryeparseBase64Binary.
Trechos de código podem ser encontradosover on GitHub.