Sunday, May 8, 2022

Java Tutorial: Base64 Class

Chapters

Overview

Base64 class consists exclusively of static methods for obtaining encoders and decoders for the Base64 encoding scheme. Base64 encodes binary data into 6-bit Base64 characters.

Base64 is useful when we want to transmit binary data over channels that only support text content. For example, Base64 is also widely used for sending e-mail attachments because SMTP, the widely used electronic mail protocol, can only transport 7-bit ASCII characters.

Base64 is widely used in World Wide Web. One of its usage is embedding image files in HTML. There are the types of Base64 that java supports.
  • Basic
  • URL and Filename safe
  • MIME
The length of Base64 characters is 6 bits. A 65-character subset of US-ASCII is used, enabling 6 bits to be represented per printable character. Base64 characters can be found in this table.

Base64 encoding length should be multiple of four. If this is not met, the encoder will add "=" as padding to compensate for the lack of characters. If you don't want the encoder to add padding, invoke withoutPadding method first before encoding binary data. For example:

String encoded = Base64.getEncoder().withoutPadding().encodeToString(input.getBytes("UTF-8"));


Basic Encoder

Basic encoder just encodes data as-is. Basic decoder rejects any characters that are not part of Base64 characters. This example demonstrates encoding data to Base64 and decoding it back to its original format.
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class SampleClass{

  public static void main(String[] args) throws
                     UnsupportedEncodingException{
    
    String input = "\u00e9zebra!!";
    System.out.println("Original");
    System.out.println(input);
    System.out.println();
    
    String encoded = Base64.getEncoder().
    encodeToString(input.getBytes("UTF-8"));
    System.out.println("Encoded");
    System.out.println(encoded);
    System.out.println();
    
    byte[] decodedBytes = 
    Base64.getDecoder().decode(encoded);
    String decodedStr = 
    new String(decodedBytes, "UTF-8");
    System.out.println("Decoded");
    System.out.println(decodedStr);
    System.out.println();
    
  }
}

Result
Original
ézebra!!

Encoded
w616ZWJyYSEh

Decoded
ézebra!!
Base64.getEncoder returns a Base64.Encoder instance using basic type encoder. Base64.getDecoder returns a Base64.Decoder instance using basic type decoder.

URL and Filename-safe

URL and Filename-safe Base64 encoder encodes data with URL-friendly and filename-friendly characters. In this encoder, "+" is replaced by "-" and "/" is replaced by "_". Those characters that are replaced have special meanings to URLs and filesystems. Those characters with special meanings may mess up the encoded data. Take a look at this table to know more about the differences between Base64 encoders.

This example demonstrates encoding URL using Base64.
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class SampleClass{

  public static void main(String[] args) throws
                     UnsupportedEncodingException{
    
    String input = "https://www.google.com/";
    System.out.println("Original");
    System.out.println(input);
    System.out.println();
    
    String encoded = Base64.getUrlEncoder().
    encodeToString(input.getBytes("UTF-8"));
    System.out.println("Encoded");
    System.out.println(encoded);
    System.out.println();
    
    byte[] decodedBytes = 
    Base64.getUrlDecoder().decode(encoded);
    String decodedStr = 
    new String(decodedBytes, "UTF-8");
    System.out.println("Decoded");
    System.out.println(decodedStr);
    System.out.println();
    
  }
}

Result
Original
https://www.google.com/

Encoded
aHR0cHM6Ly93d3cuZ29...

Decoded
https://www.google.com/

Base64.getUrlEncoder returns a Base64.Encoder instance using URL and filename-safe type encoder. Base64.getUrlDecoder returns a Base64.Decoder instance using URL and filename-safe type decoder.

MIME

Multipurpose Internet Mail Extensions(MIME) is an Internet standard that extends the format of email messages to support text in character sets other than ASCII, as well as attachments of audio, video, images, and application programs.

Base64 alphabet is supported by MIME character set. Thus, Base64 MIME encoder is MIME-friendly. This example demonstrates encoding using Base64 MIME encoder.
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Base64;

public class SampleClass{

  public static void main(String[] args) throws
                     UnsupportedEncodingException,
                     IOException{
    
    File file = new File("files/image.png");
    byte[] fileBytes = 
    Files.readAllBytes(file.toPath());
    
    System.out.println("Original");
    for(byte b : fileBytes)
      System.out.print(b + " ");
    System.out.println();
    
    String encoded = Base64.getMimeEncoder().
    encodeToString(fileBytes);
    System.out.println("Encoded");
    System.out.println(encoded);
    System.out.println();
    
    byte[] decodedBytes = 
    Base64.getMimeDecoder().decode(encoded);
    String decodedStr = 
    new String(decodedBytes, "UTF-8");
    System.out.println("Decoded");
    for(byte b : fileBytes)
      System.out.print(b + " ");
  }
}

Result
Original
-119 80 78 71 13 10 26...
Encoded
iVBORw0Kggo...

Decoded
-119 80 78 71 13 10 26...
Base64.getMimeEncoder returns a Base64.Encoder instance using MIME type encoder. Base64.getMimeDecoder returns a Base64.Decoder instance using MIME type decoder. The length of lines in the output is no longer than 76 characters. Also, each line end with CR+LF(\r\n).

If you want to change the character per length and line separators, invoke getMimeEncoder(int lineLength, byte[] lineSeparator). In the example above, the encoded bytes of the image file can be used in HTML. For example:
<div>
  <p>Taken from wikpedia</p>
  <img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUA
    AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
        9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />
</div>

No comments:

Post a Comment