Codificação e decodificação Java Base64

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.

Read more

Hashing SHA-256 e SHA3-256 em Java

Um guia rápido e prático para o hash SHA-256 em Java

Read more

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.

Read more

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.