Prerequisite : What is base64 Encoding and why we encode strings to base64 format
Base64 encoding is performed at sending node before transmitting bits over a network, and receiving node decodes that encoded data back to original ASCII string.
Base64 character set is
// 64 characters
char_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz0123456789+/"
Examples:
Input : TUVO04= // (Encoded into base64 format)
Output : MENON // (Decoded back to ASCII string)Input : Z2Vla3Nmb3JnZWVrcw==
Output : geeksforgeeks
Approach:
- Here each character in encoded string is considered to be made of 6 bits. We will take 4 characters each from Encoded String at one time i.e 4 * 6 = 24 bits. For each 4 characters of encoded string we will produce 3 characters of original string which will be of 8 bits each i.e 3 * 8 = 24 bits.
- Find their respective position in char_set and store it inside a variable (num) by using '|' OR operator for storing bits and (LEFT - SHIFT) by 6 to make room for another 6 bits.
NOTE : We used '=' in encoder to substitute for 2 missing bits, So here in decoder we have to reverse the process. Whenever we encounter a '=' we have to delete 2 bits of num by using (RIGHT - SHIFT) by 2. - After we have stored all the bits in num we will retrieve them in groups of 8, by using & operator with 255 (11111111), that will store the 8 bits from num and that will be our original character from ASCII string.
// C++ Program to decode a base64
// Encoded string back to ASCII string
#include <bits/stdc++.h>
using namespace std;
#define SIZE 100
/* char_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz0123456789+/" */
char* base64Decoder(char encoded[], int len_str)
{
char* decoded_string;
decoded_string = (char*)malloc(sizeof(char) * SIZE);
int i, j, k = 0;
// stores the bitstream.
int num = 0;
// count_bits stores current
// number of bits in num.
int count_bits = 0;
// selects 4 characters from
// encoded string at a time.
// find the position of each encoded
// character in char_set and stores in num.
for (i = 0; i < len_str; i += 4)
{
num = 0, count_bits = 0;
for (j = 0; j < 4; j++)
{
// make space for 6 bits.
if (encoded[i + j] != '=')
{
num = num << 6;
count_bits += 6;
}
/* Finding the position of each encoded
character in char_set
and storing in "num", use OR
'|' operator to store bits.*/
// encoded[i + j] = 'E', 'E' - 'A' = 5
// 'E' has 5th position in char_set.
if (encoded[i + j] >= 'A' && encoded[i + j] <= 'Z')
num = num | (encoded[i + j] - 'A');
// encoded[i + j] = 'e', 'e' - 'a' = 5,
// 5 + 26 = 31, 'e' has 31st position in char_set.
else if (encoded[i + j] >= 'a' && encoded[i + j] <= 'z')
num = num | (encoded[i + j] - 'a' + 26);
// encoded[i + j] = '8', '8' - '0' = 8
// 8 + 52 = 60, '8' has 60th position in char_set.
else if (encoded[i + j] >= '0' && encoded[i + j] <= '9')
num = num | (encoded[i + j] - '0' + 52);
// '+' occurs in 62nd position in char_set.
else if (encoded[i + j] == '+')
num = num | 62;
// '/' occurs in 63rd position in char_set.
else if (encoded[i + j] == '/')
num = num | 63;
// ( str[i + j] == '=' ) remove 2 bits
// to delete appended bits during encoding.
else {
num = num >> 2;
count_bits -= 2;
}
}
while (count_bits != 0)
{
count_bits -= 8;
// 255 in binary is 11111111
decoded_string[k++] = (num >> count_bits) & 255;
}
}
// place NULL character to mark end of string.
decoded_string[k] = '\0';
return decoded_string;
}
// Driver code
int main()
{
char encoded_string[] = "TUVOT04=";
int len_str = sizeof(encoded_string) / sizeof(encoded_string[0]);
// Do not count last NULL character.
len_str -= 1;
cout <<"Encoded string : " <<
encoded_string << endl;
cout <<"Decoded string : " <<
base64Decoder(encoded_string, len_str) << endl;
return 0;
}
// This code is contributed by
// shubhamsingh10
// C Program to decode a base64
// Encoded string back to ASCII string
#include <stdio.h>
#include <stdlib.h>
#define SIZE 100
/* char_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz0123456789+/" */
char* base64Decoder(char encoded[], int len_str)
{
char* decoded_string;
decoded_string = (char*)malloc(sizeof(char) * SIZE);
int i, j, k = 0;
// stores the bitstream.
int num = 0;
// count_bits stores current
// number of bits in num.
int count_bits = 0;
// selects 4 characters from
// encoded string at a time.
// find the position of each encoded
// character in char_set and stores in num.
for (i = 0; i < len_str; i += 4) {
num = 0, count_bits = 0;
for (j = 0; j < 4; j++) {
// make space for 6 bits.
if (encoded[i + j] != '=') {
num = num << 6;
count_bits += 6;
}
/* Finding the position of each encoded
character in char_set
and storing in "num", use OR
'|' operator to store bits.*/
// encoded[i + j] = 'E', 'E' - 'A' = 5
// 'E' has 5th position in char_set.
if (encoded[i + j] >= 'A' && encoded[i + j] <= 'Z')
num = num | (encoded[i + j] - 'A');
// encoded[i + j] = 'e', 'e' - 'a' = 5,
// 5 + 26 = 31, 'e' has 31st position in char_set.
else if (encoded[i + j] >= 'a' && encoded[i + j] <= 'z')
num = num | (encoded[i + j] - 'a' + 26);
// encoded[i + j] = '8', '8' - '0' = 8
// 8 + 52 = 60, '8' has 60th position in char_set.
else if (encoded[i + j] >= '0' && encoded[i + j] <= '9')
num = num | (encoded[i + j] - '0' + 52);
// '+' occurs in 62nd position in char_set.
else if (encoded[i + j] == '+')
num = num | 62;
// '/' occurs in 63rd position in char_set.
else if (encoded[i + j] == '/')
num = num | 63;
// ( str[i + j] == '=' ) remove 2 bits
// to delete appended bits during encoding.
else {
num = num >> 2;
count_bits -= 2;
}
}
while (count_bits != 0) {
count_bits -= 8;
// 255 in binary is 11111111
decoded_string[k++] = (num >> count_bits) & 255;
}
}
// place NULL character to mark end of string.
decoded_string[k] = '\0';
return decoded_string;
}
// Driver function
int main()
{
char encoded_string[] = "TUVOT04=";
int len_str = sizeof(encoded_string) / sizeof(encoded_string[0]);
// Do not count last NULL character.
len_str -= 1;
printf("Encoded string : %s\n", encoded_string);
printf("Decoded_string : %s\n", base64Decoder(encoded_string, len_str));
return 0;
}
// Java Program to decode a base64
// Encoded String back to ASCII String
class GFG
{
static final int SIZE = 100;
/* char_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz0123456789+/" */
static String base64Decoder(char encoded[], int len_str)
{
char []decoded_String;
decoded_String = new char[SIZE];
int i, j, k = 0;
// stores the bitstream.
int num = 0;
// count_bits stores current
// number of bits in num.
int count_bits = 0;
// selects 4 characters from
// encoded String at a time.
// find the position of each encoded
// character in char_set and stores in num.
for (i = 0; i < len_str; i += 4)
{
num = 0; count_bits = 0;
for (j = 0; j < 4; j++)
{
// make space for 6 bits.
if (encoded[i + j] != '=')
{
num = num << 6;
count_bits += 6;
}
/* Finding the position of each encoded
character in char_set
and storing in "num", use OR
'|' operator to store bits.*/
// encoded[i + j] = 'E', 'E' - 'A' = 5
// 'E' has 5th position in char_set.
if (encoded[i + j] >= 'A' && encoded[i + j] <= 'Z')
num = num | (encoded[i + j] - 'A');
// encoded[i + j] = 'e', 'e' - 'a' = 5,
// 5 + 26 = 31, 'e' has 31st position in char_set.
else if (encoded[i + j] >= 'a' && encoded[i + j] <= 'z')
num = num | (encoded[i + j] - 'a' + 26);
// encoded[i + j] = '8', '8' - '0' = 8
// 8 + 52 = 60, '8' has 60th position in char_set.
else if (encoded[i + j] >= '0' && encoded[i + j] <= '9')
num = num | (encoded[i + j] - '0' + 52);
// '+' occurs in 62nd position in char_set.
else if (encoded[i + j] == '+')
num = num | 62;
// '/' occurs in 63rd position in char_set.
else if (encoded[i + j] == '/')
num = num | 63;
// ( str[i + j] == '=' ) remove 2 bits
// to delete appended bits during encoding.
else
{
num = num >> 2;
count_bits -= 2;
}
}
while (count_bits != 0) {
count_bits -= 8;
// 255 in binary is 11111111
decoded_String[k++] = (char)
((num >> count_bits) & 255);
}
}
return String.valueOf(decoded_String);
}
// Driver code
public static void main(String[] args)
{
char encoded_String[] = "TUVOT04=".toCharArray();
int len_str = encoded_String.length;
// Do not count last null character.
len_str -= 1;
System.out.printf("Encoded String : %s\n",
String.valueOf(encoded_String));
System.out.printf("Decoded_String : %s\n",
base64Decoder(encoded_String, len_str));
}
}
// This code is contributed by 29AjayKumar
# Python program to decode a base64
# Encoded String back to ASCII String
SIZE = 100
# char_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ
# abcdefghijklmnopqrstuvwxyz0123456789+/"
def base64Decoder(encoded, len_str):
decoded_String = [''] * SIZE
i, j, k = 0, 0, 0
# stores the bitstream.
num = 0
# count_bits stores current
# number of bits in num.
count_bits = 0
# selects 4 characters from
# encoded String at a time.
# find the position of each encoded
# character in char_set and stores in num.
while i < len_str:
num, count_bits = 0, 0
for j in range(4):
# make space for 6 bits.
if encoded[i + j] != '=':
num = num << 6
count_bits += 6
# Finding the position of each encoded
# character in char_set
# and storing in "num", use OR
# '|' operator to store bits.
# encoded[i + j] = 'E', 'E' - 'A' = 5
# 'E' has 5th position in char_set.
if 'A' <= encoded[i + j] <= 'Z':
num = num | (ord(encoded[i + j]) - ord('A'))
# encoded[i + j] = 'e', 'e' - 'a' = 5,
# 5 + 26 = 31, 'e' has 31st position in char_set.
elif 'a' <= encoded[i + j] <= 'z':
num = num | (ord(encoded[i + j]) - ord('a') + 26)
# encoded[i + j] = '8', '8' - '0' = 8
# 8 + 52 = 60, '8' has 60th position in char_set.
elif '0' <= encoded[i + j] <= '9':
num = num | (ord(encoded[i + j]) - ord('0') + 52)
# '+' occurs in 62nd position in char_set.
elif encoded[i + j] == '+':
num = num | 62
# '/' occurs in 63rd position in char_set.
elif encoded[i + j] == '/':
num = num | 63
# ( str[i + j] == '=' ) remove 2 bits
# to delete appended bits during encoding.
else:
num = num >> 2
count_bits -= 2
while count_bits != 0:
count_bits -= 8
# 255 in binary is 11111111
decoded_String[k] = chr((num >> count_bits) & 255)
k += 1
i += 4
return ''.join(decoded_String)
# Driver code
if __name__ == '__main__':
encoded_String = "TUVOT04="
len_str = len(encoded_String)
# Do not count last null character.
len_str -= 1
print("Encoded String : ", encoded_String)
print("Decoded String : ", base64Decoder(encoded_String, len_str))
// C# Program to decode a base64
// Encoded String back to ASCII String
using System;
class GFG
{
static readonly int SIZE = 100;
/* char_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz0123456789+/" */
static String base64Decoder(char []encoded, int len_str)
{
char []decoded_String;
decoded_String = new char[SIZE];
int i, j, k = 0;
// stores the bitstream.
int num = 0;
// count_bits stores current
// number of bits in num.
int count_bits = 0;
// selects 4 characters from
// encoded String at a time.
// find the position of each encoded
// character in char_set and stores in num.
for (i = 0; i < len_str; i += 4)
{
num = 0; count_bits = 0;
for (j = 0; j < 4; j++)
{
// make space for 6 bits.
if (encoded[i + j] != '=')
{
num = num << 6;
count_bits += 6;
}
/* Finding the position of each encoded
character in char_set
and storing in "num", use OR
'|' operator to store bits.*/
// encoded[i + j] = 'E', 'E' - 'A' = 5
// 'E' has 5th position in char_set.
if (encoded[i + j] >= 'A' && encoded[i + j] <= 'Z')
num = num | (encoded[i + j] - 'A');
// encoded[i + j] = 'e', 'e' - 'a' = 5,
// 5 + 26 = 31, 'e' has 31st position in char_set.
else if (encoded[i + j] >= 'a' && encoded[i + j] <= 'z')
num = num | (encoded[i + j] - 'a' + 26);
// encoded[i + j] = '8', '8' - '0' = 8
// 8 + 52 = 60, '8' has 60th position in char_set.
else if (encoded[i + j] >= '0' && encoded[i + j] <= '9')
num = num | (encoded[i + j] - '0' + 52);
// '+' occurs in 62nd position in char_set.
else if (encoded[i + j] == '+')
num = num | 62;
// '/' occurs in 63rd position in char_set.
else if (encoded[i + j] == '/')
num = num | 63;
// ( str[i + j] == '=' ) remove 2 bits
// to delete appended bits during encoding.
else
{
num = num >> 2;
count_bits -= 2;
}
}
while (count_bits != 0)
{
count_bits -= 8;
// 255 in binary is 11111111
decoded_String[k++] = (char)
((num >> count_bits) & 255);
}
}
return String.Join("",decoded_String);
}
// Driver code
public static void Main(String[] args)
{
char []encoded_String = "TUVOT04=".ToCharArray();
int len_str = encoded_String.Length;
// Do not count last null character.
len_str -= 1;
Console.Write("Encoded String : {0}\n",
String.Join("",encoded_String));
Console.Write("Decoded_String : {0}\n",
base64Decoder(encoded_String, len_str));
}
}
// This code is contributed by 29AjayKumar
<script>
// JavaScript Program to decode a base64
// Encoded String back to ASCII String
let SIZE = 100;
/* char_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz0123456789+/" */
function base64Decoder(encoded,len_str)
{
let decoded_String;
decoded_String = new Array(SIZE);
let i, j, k = 0;
// stores the bitstream.
let num = 0;
// count_bits stores current
// number of bits in num.
let count_bits = 0;
// selects 4 characters from
// encoded String at a time.
// find the position of each encoded
// character in char_set and stores in num.
for (i = 0; i < len_str; i += 4)
{
num = 0; count_bits = 0;
for (j = 0; j < 4; j++)
{
// make space for 6 bits.
if (encoded[i + j] != '=')
{
num = num << 6;
count_bits += 6;
}
/* Finding the position of each encoded
character in char_set
and storing in "num", use OR
'|' operator to store bits.*/
// encoded[i + j] = 'E', 'E' - 'A' = 5
// 'E' has 5th position in char_set.
if (encoded[i + j].charCodeAt(0) >=
'A'.charCodeAt(0) && encoded[i + j].charCodeAt(0)
<= 'Z'.charCodeAt(0))
num = num | (encoded[i + j].charCodeAt(0) -
'A'.charCodeAt(0));
// encoded[i + j] = 'e', 'e' - 'a' = 5,
// 5 + 26 = 31, 'e' has 31st position in char_set.
else if (encoded[i + j].charCodeAt(0) >=
'a'.charCodeAt(0) && encoded[i + j].charCodeAt(0) <=
'z'.charCodeAt(0))
num = num | (encoded[i + j].charCodeAt(0) -
'a'.charCodeAt(0) + 26);
// encoded[i + j] = '8', '8' - '0' = 8
// 8 + 52 = 60, '8' has 60th position in char_set.
else if (encoded[i + j].charCodeAt(0) >=
'0'.charCodeAt(0) && encoded[i + j].charCodeAt(0) <=
'9'.charCodeAt(0))
num = num | (encoded[i + j].charCodeAt(0) -
'0'.charCodeAt(0) + 52);
// '+' occurs in 62nd position in char_set.
else if (encoded[i + j] == '+')
num = num | 62;
// '/' occurs in 63rd position in char_set.
else if (encoded[i + j] == '/')
num = num | 63;
// ( str[i + j] == '=' ) remove 2 bits
// to delete appended bits during encoding.
else
{
num = num >> 2;
count_bits -= 2;
}
}
while (count_bits != 0) {
count_bits -= 8;
// 255 in binary is 11111111
decoded_String[k++] = String.fromCharCode
((num >> count_bits) & 255);
}
}
return (decoded_String);
}
// Driver code
let encoded_String = "TUVOT04=".split("");
let len_str = encoded_String.length;
// Do not count last null character.
len_str -= 1;
document.write("Encoded String : " +
(encoded_String).join("")+"<br>");
document.write("Decoded_String : "+
base64Decoder(encoded_String, len_str).join("")+"<br>");
// This code is contributed by rag2127
</script>
Output
Encoded string : TUVOT04= Decoded string : MENON
Time Complexity: O(N)
Space Complexity: O(1)
Another Approach using python in-built module: base64
- Assign the input string to the variable named encoded_string.
- Decode the encoded string using base64.b64decode() and store the result in a variable named as decoded.
- Decode the decoded string from bytes to ASCII using decoded.decode('ascii') and store the result in a variable named as decoded_string.
- Return the decoded_string.
#include <bits/stdc++.h>
using namespace std;
// Function to decode a Base64 encoded string
string base64Decoder(string encoded) {
string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
string decoded;
vector<int> T(256, -1);
for (int i = 0; i < 64; i++) T[base64_chars[i]] = i;
int val = 0, valb = -8;
for (char c : encoded) {
if (T[c] == -1) break;
val = (val << 6) + T[c];
valb += 6;
if (valb >= 0) {
decoded.push_back(char((val >> valb) & 0xFF));
valb -= 8;
}
}
return decoded;
}
// Driver code
int main() {
string encodedString = "TUVOT04=";
cout << "Encoded string: " << encodedString <<endl;
string decodedString = base64Decoder(encodedString);
cout << "Decoded string: " << decodedString << endl;
return 0;
}
// Java program for the above approach
import java.util.Base64;
public class Main {
public static String base64Decoder(String encoded) {
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes);
return decoded;
}
// Driver code
public static void main(String[] args) {
String encodedString = "TUVOT04=";
System.out.println("Encoded string: " + encodedString);
String decodedString = base64Decoder(encodedString);
System.out.println("Decoded string: " + decodedString);
}
}
# Python program for the above approach
import base64
def base64Decoder(encoded):
decoded = base64.b64decode(encoded)
return decoded.decode('ascii')
# Driver code
if __name__ == '__main__':
encoded_string = "TUVOT04="
print("Encoded string:", encoded_string)
decoded_string = base64Decoder(encoded_string)
print("Decoded string:", decoded_string)
# This code is contributed by Prince Kumar
// C# program for the above approach
using System;
using System.Text;
public class MainClass
{
public static string Base64Decoder(string encoded)
{
byte[] decodedBytes = Convert.FromBase64String(encoded);
string decoded = Encoding.UTF8.GetString(decodedBytes);
return decoded;
}
// Driver code
public static void Main()
{
string encodedString = "TUVOT04=";
Console.WriteLine("Encoded string: " + encodedString);
string decodedString = Base64Decoder(encodedString);
Console.WriteLine("Decoded string: " + decodedString);
}
}
// Javascript program for the above approach
function base64Decoder(encoded) {
let decoded = Buffer.from(encoded, 'base64');
return decoded.toString('ascii');
}
// Driver code
let encoded_string = "TUVOT04=";
console.log("Encoded string:", encoded_string);
let decoded_string = base64Decoder(encoded_string);
console.log("Decoded string:", decoded_string);
// This code is contributed codebraxnzt
Output
Encoded string: TUVOT04= Decoded string: MENON
Time Complexity: O(n), where n is the size of the input string
Auxiliary Space: O(n), where n is the size of the input string