Ты наверное замечал в конце каждого закодированного знаки уравнения? Их там может быть 1, 2 или 0, это паддинг добавляемый в конце если изначальное количество байт не поделилось поравну. А делится изначальный бинарный поток на кусочки по 3 байта (задача кодировки передавать любые данные в аски, чтобы можно через текстовые интерфейсы типа строки браузера, формы, файла текстового письма их отправлять).
Так вот, у нас есть выходной алфавит из 64 возможных символов, это 2^6 состояний на один символ, мы кодируем 3 байта (2^8)^3, это 24 бита, 2^24. Сколько нужно символов из алфавита в 2^6 символов? Очевидно что (2^8)^3 = 2^24 = (2^6)^4 -> из 3 байт входных данных получится 4 символа из алфавита кодирования. Если нужно ручками кодировать b64 возьми входные данные, подели по 3 байта, переведи в бинарный вид, в бинарном виде 24 бита раздели на четыре шестибитных числа, переведи их по Base64 табличке в аски текст и заполни в конце знаками "=" пока длинна выходного текста не будет кратна трём