Base64 Implementation in Java!

Head spinning!

Base64Encoder.java
package biz.tugay.Base64Encoder;
 
public class Base64Encoder {
 
    private final Base64EncoderHelper base64EncoderHelper = new Base64EncoderHelper();
    private final char[] base64IndexTable = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 
            'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 
            'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 
            'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', 
            '5', '6', '7', '8', '9', '+', '/', '=', '"'};
 
    public String base64Encode(final byte[] input) {
        final StringBuilder stringBuilder = new StringBuilder();
 
        byte[] byteChunk = null;
 
        for (int i = 0; i < input.length; i++) {
            final int modulus = i % 3;
            if (modulus == 0) {
                byteChunk = new byte[3];
            }
 
            byteChunk[modulus] = input[i];
 
            if (modulus == 2 || i == input.length - 1) {
                final int data = base64EncoderHelper.convert3ByteChunkTo24Bits(byteChunk);
                final byte[] bytes = base64EncoderHelper.convert24BitDataTo4ByteChunk(data);
 
                if (modulus == 0) {
                    bytes[2] = 64;
                    bytes[3] = 64;
                }
 
                if (modulus == 1) {
                    bytes[3] = 64;
                }
 
                for (byte b : bytes) {
                    stringBuilder.append(base64IndexTable[b]);
                }
            }
        }
 
        return stringBuilder.toString();
    }
}

Base64EncoderHelper.java
package biz.tugay.Base64Encoder;
 
public class Base64EncoderHelper {
 
    public int convert3ByteChunkTo24Bits(final byte[] bytes) {
        int bitsFor3ByteChunk = 0;
 
        final char byte_0 = (char) bytes[0];
        final char byte_1 = (char) bytes[1];
        final char byte_2 = (char) bytes[2];
 
        bitsFor3ByteChunk = bitsFor3ByteChunk | (byte_0 & 0b00000000_11111111);
 
        bitsFor3ByteChunk = bitsFor3ByteChunk << 8;
        bitsFor3ByteChunk = bitsFor3ByteChunk | (byte_1 & 0b00000000_11111111);
 
        bitsFor3ByteChunk = bitsFor3ByteChunk << 8;
        bitsFor3ByteChunk = bitsFor3ByteChunk | (byte_2 & 0b00000000_11111111);
 
        return bitsFor3ByteChunk & 0b00000000_11111111_11111111_11111111;
    }
 
    public byte[] convert24BitDataTo4ByteChunk(int data) {
        byte[] bytes = new byte[4];
        bytes[3] = (byte) (0b00000000_00000000_00000000_00111111 & data);
        data = data >> 6;
        bytes[2] = (byte) (0b00000000_00000000_00000000_00111111 & data);
        data = data >> 6;
        bytes[1] = (byte) (0b00000000_00000000_00000000_00111111 & data);
        data = data >> 6;
        bytes[0] = (byte) (0b00000000_00000000_00000000_00111111 & data);
        return bytes;
    }
}

Base64EncoderTest.java
package biz.tugay.Base64Encoder;
 
public class Base64EncoderTest {
 
    private final Base64Encoder base64Encoder = new Base64Encoder();
 
    public static void main(String[] args) {
        final Base64EncoderTest base64EncoderTest = new Base64EncoderTest();
        base64EncoderTest.test_01();
        base64EncoderTest.test_02();
    }
 
    private void test_01() {
        final byte m = 0x4D; // 0100_1101
        final byte a = 0x61; // 0110_0001
        final byte n = 0x6E; // 0110_1110
 
        final byte[] man = {m, a, n};
        final String base64Encode = base64Encoder.base64Encode(man);
 
        assert base64Encode.equals("TWFu");
    }
 
    private void test_02() {
        final byte ca = (byte) 0xCA;
        final byte fe = (byte) 0xFE;
        final byte ba = (byte) 0xBA;
 
        final byte[] man = {ca, fe, ba};
        final String base64Encode = base64Encoder.base64Encode(man);
 
        assert base64Encode.equals("yv66");
    }
}

Base64EncoderHelperTest.java
package biz.tugay.Base64Encoder;
 
public class Base64EncoderHelperTest {
 
    private final Base64EncoderHelper base64EncoderHelper = new Base64EncoderHelper();
 
    public static void main(String[] args) {
        final Base64EncoderHelperTest base64EncoderHelperTest = new Base64EncoderHelperTest();
        base64EncoderHelperTest.test_01();
        base64EncoderHelperTest.test_02();
        base64EncoderHelperTest.test_03();
        base64EncoderHelperTest.test_04();
    }
 
    private void test_01() {
        final byte M = 0x4D; // 0100_1101
        final byte a = 0x61; // 0110_0001
        final byte n = 0x6E; // 0110_1110
 
        final byte[] man = {M, a, n};
        final int bytesIn24Bits = base64EncoderHelper.convert3ByteChunkTo24Bits(man);
 
        assert bytesIn24Bits == 0b0000_0000_0100_1101_0110_0001_0110_1110;
    }
 
    private void test_02() {
        final byte[] man = {(byte) (0b1111_1111), (byte) (0b1111_1111), (byte) (0b1111_1111)};
        final int bytesIn24Bits = base64EncoderHelper.convert3ByteChunkTo24Bits(man);
 
        assert bytesIn24Bits == 0b0000_0000_1111_1111_1111_1111_1111_1111;
    }
 
    private void test_03() {
        // input  = 5071214 = 0000_0000_0100_1101_0110_0001_0110_1110
 
        // output = 00101110 = 46
        //          00000101 =  5
        //          00010110 = 22
        //          00010011 = 19
 
        final byte[] bytes = base64EncoderHelper.convert24BitDataTo4ByteChunk(5071214);
 
        assert bytes[0] == 46;
        assert bytes[1] == 5;
        assert bytes[2] == 22;
        assert bytes[3] == 19;
    }
 
    private void test_04() {
        final byte c = (byte) 0b1100_1010;
        final byte a = 0xA;
        final byte f = 0xF;
        final byte e = 0xE;
 
 
        final byte[] man = {c, a, f};
        final int bytesIn24Bits = base64EncoderHelper.convert3ByteChunkTo24Bits(man);
 
        assert bytesIn24Bits == 0b0000_0000_0100_1101_0110_0001_0110_1110;
    }
}

Base64EncoderApp.java
import biz.tugay.Base64Encoder.Base64Encoder;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
 
public class Base64EncoderApp {
 
    public static void main(String[] args) throws IOException {
        final Base64Encoder base64Encoder = new Base64Encoder();
 
        final File file = new File(args[0]);
        final FileInputStream fileInputStream = new FileInputStream(file);
 
        final byte[] bytes = new byte[(int) file.length()];
        final byte[] b = new byte[1];
 
        int counter = 0;
 
        while (fileInputStream.read(b) != -1) {
            bytes[counter] = b[0];
            counter++;
        }
 
        final String base64Encode = base64Encoder.base64Encode(bytes);
        System.out.println(base64Encode);
    }
}

I did some tests comparing my results to this page and all seemed fine! But why do we use Base64 encoding in the first place? Here is the answer. And what is Base64 encoding again? Here is the answer..