Whiz Tools

Kodowanie/ Dekodowanie Base64

Konwertuj tekst na kodowanie Base64 i odwrotnie

Kopiuj

Kodowanie i dekodowanie Base64

Wprowadzenie

Base64 to schemat kodowania binarnego na tekst, który reprezentuje dane binarne w formacie ciągu ASCII. Został zaprojektowany w celu przenoszenia danych przechowywanych w formatach binarnych przez kanały, które niezawodnie obsługują tylko treści tekstowe. Kodowanie Base64 konwertuje dane binarne na zestaw 64 znaków (stąd nazwa), które można bezpiecznie przesyłać przez protokoły oparte na tekście bez uszkodzenia danych.

Zestaw znaków Base64 składa się z:

  • Wielkich liter A-Z (26 znaków)
  • Małych liter a-z (26 znaków)
  • Cyfr 0-9 (10 znaków)
  • Dwóch dodatkowych znaków, zazwyczaj "+" i "/" (2 znaki)

To narzędzie pozwala łatwo kodować tekst w formacie Base64 lub dekodować ciągi Base64 z powrotem do ich oryginalnego tekstu. Jest szczególnie przydatne dla programistów, profesjonalistów IT i każdego, kto pracuje z danymi, które muszą być przesyłane bezpiecznie przez kanały oparte na tekście.

Jak działa kodowanie Base64

Proces kodowania

Kodowanie Base64 działa poprzez konwersję każdej grupy trzech bajtów (24 bity) danych binarnych na cztery znaki Base64. Proces ten przebiega według następujących kroków:

  1. Przekształcenie tekstu wejściowego w jego reprezentację binarną (przy użyciu kodowania ASCII lub UTF-8)
  2. Grupowanie danych binarnych w kawałki po 24 bity (3 bajty)
  3. Podział każdej grupy 24-bitowej na cztery grupy 6-bitowe
  4. Przekształcenie każdej grupy 6-bitowej na odpowiadający znak Base64

Gdy długość wejścia nie jest podzielna przez 3, dodawane są znaki "=" w celu utrzymania proporcji 4:3 długości wyjścia do długości wejścia.

Reprezentacja matematyczna

Dla sekwencji bajtów b1,b2,b3b_1, b_2, b_3, odpowiadające znaki Base64 c1,c2,c3,c4c_1, c_2, c_3, c_4 są obliczane jako:

c1=Base64[(b1>>2)]c_1 = \text{Base64}[(b_1 >> 2)]
c2=Base64[((b1&3)<<4)(b2>>4)]c_2 = \text{Base64}[((b_1 \& 3) << 4) | (b_2 >> 4)]
c3=Base64[((b2&15)<<2)(b3>>6)]c_3 = \text{Base64}[((b_2 \& 15) << 2) | (b_3 >> 6)]
c4=Base64[(b3&63)]c_4 = \text{Base64}[(b_3 \& 63)]

Gdzie Base64[i]\text{Base64}[i] reprezentuje ii-ty znak w alfabecie Base64.

Proces dekodowania

Dekodowanie Base64 odwraca proces kodowania:

  1. Przekształcenie każdego znaku Base64 na jego wartość 6-bitową
  2. Konkatenacja tych wartości 6-bitowych
  3. Grupowanie bitów w kawałki 8-bitowe (bajty)
  4. Przekształcenie każdego bajtu na odpowiadający znak

Padding

Gdy liczba bajtów do zakodowania nie jest podzielna przez 3, stosuje się padding:

  • Jeśli pozostał jeden bajt, jest on konwertowany na dwa znaki Base64, a następnie dodawane są "=="
  • Jeśli pozostały dwa bajty, są one konwertowane na trzy znaki Base64, a następnie dodawany jest "="

Przykład

Zakodujmy tekst "Hello" na Base64:

  1. Reprezentacja ASCII "Hello": 72 101 108 108 111
  2. Reprezentacja binarna: 01001000 01100101 01101100 01101100 01101111
  3. Grupowanie w kawałki 6-bitowe: 010010 000110 010101 101100 011011 000110 1111
  4. Ostatni kawałek ma tylko 4 bity, więc dodajemy zera: 010010 000110 010101 101100 011011 000110 111100
  5. Konwersja na dziesiętne: 18, 6, 21, 44, 27, 6, 60
  6. Sprawdzenie w alfabecie Base64: S, G, V, s, b, G, 8
  7. Wynik to "SGVsbG8="

Zauważ padding "=" na końcu, ponieważ długość wejścia (5 bajtów) nie jest podzielna przez 3.

Wzór

Ogólny wzór do obliczania długości zakodowanego ciągu Base64 to:

encoded_length=4×input_length3\text{encoded\_length} = 4 \times \lceil \frac{\text{input\_length}}{3} \rceil

Gdzie x\lceil x \rceil reprezentuje funkcję sufitową (zaokrąglającą w górę do najbliższej liczby całkowitej).

Przykłady użycia

Kodowanie Base64 jest szeroko stosowane w różnych aplikacjach:

  1. Załączniki e-mailowe: MIME (Multipurpose Internet Mail Extensions) używa Base64 do kodowania binarnych załączników w e-mailach.

  2. Adresy URL danych: Osadzanie małych obrazów, czcionek lub innych zasobów bezpośrednio w HTML, CSS lub JavaScript przy użyciu schematu URL data:.

  3. Komunikacja API: Bezpieczne przesyłanie danych binarnych w ładunkach JSON lub innych tekstowych formatach API.

  4. Przechowywanie danych binarnych w formatach tekstowych: Gdy dane binarne muszą być przechowywane w XML, JSON lub innych formatach opartych na tekście.

  5. Systemy uwierzytelniania: Podstawowe uwierzytelnianie w HTTP używa kodowania Base64 (choć nie dla bezpieczeństwa, tylko dla kodowania).

  6. Kryptografia: Jako część różnych protokołów i systemów kryptograficznych, często do kodowania kluczy lub certyfikatów.

  7. Wartości ciasteczek: Kodowanie złożonych struktur danych do przechowywania w ciasteczkach.

Alternatywy

Chociaż Base64 jest szeroko stosowane, istnieją alternatywy, które mogą być bardziej odpowiednie w niektórych sytuacjach:

  1. Bezpieczne Base64 w URL: Wariant, który używa "-" i "_" zamiast "+" i "/", aby uniknąć problemów z kodowaniem URL. Przydatne dla danych, które będą zawarte w adresach URL.

  2. Base32: Używa zestawu 32 znaków, co skutkuje dłuższym wyjściem, ale lepszą czytelnością dla ludzi i niewrażliwością na wielkość liter.

  3. Kodowanie szesnastkowe: Prosta konwersja na szesnastkowe, która jest mniej wydajna (podwaja rozmiar), ale bardzo prosta i szeroko wspierana.

  4. Transfer binarny: Dla dużych plików lub gdy wydajność jest kluczowa, preferowane są bezpośrednie protokoły transferu binarnego, takie jak HTTP z odpowiednimi nagłówkami Content-Type.

  5. Kompresja + Base64: Dla dużych danych tekstowych, kompresja przed kodowaniem może złagodzić wzrost rozmiaru.

  6. Serializacja JSON/XML: Dla danych strukturalnych użycie natywnej serializacji JSON lub XML może być bardziej odpowiednie niż kodowanie Base64.

Historia

Kodowanie Base64 ma swoje korzenie w wczesnych systemach komputerowych i telekomunikacyjnych, w których dane binarne musiały być przesyłane przez kanały zaprojektowane do obsługi tekstu.

Formalna specyfikacja Base64 została po raz pierwszy opublikowana w 1987 roku jako część RFC 989, która definiowała prywatną pocztę elektroniczną (PEM). Została ona później zaktualizowana w RFC 1421 (1993) i RFC 2045 (1996, jako część MIME).

Termin "Base64" pochodzi od faktu, że kodowanie używa 64 różnych znaków ASCII do reprezentowania danych binarnych. Ten wybór 64 znaków był zamierzony, ponieważ 64 jest potęgą 2 (2^6), co sprawia, że konwersja między binarnym a Base64 jest wydajna.

Z biegiem czasu pojawiło się kilka wariantów Base64:

  • Standardowe Base64: Zdefiniowane w RFC 4648, używające A-Z, a-z, 0-9, +, / i = do paddingu
  • Bezpieczne Base64 w URL: Używa - i _ zamiast + i / w celu uniknięcia problemów z kodowaniem URL
  • Bezpieczne Base64 dla nazw plików: Podobne do bezpiecznego Base64 w URL, zaprojektowane do użycia w nazwach plików
  • Zmodyfikowane Base64 dla IMAP: Używane w protokole IMAP z innym zestawem znaków specjalnych

Pomimo że ma ponad trzy dekady, Base64 pozostaje fundamentalnym narzędziem w nowoczesnym przetwarzaniu, szczególnie w dobie aplikacji internetowych i API, które opierają się na formatach danych tekstowych, takich jak JSON.

Przykłady kodu

Oto przykłady kodowania i dekodowania Base64 w różnych językach programowania:

// Kodowanie/Dekodowanie Base64 w JavaScript
function encodeToBase64(text) {
  return btoa(text);
}

function decodeFromBase64(base64String) {
  try {
    return atob(base64String);
  } catch (e) {
    throw new Error("Nieprawidłowy ciąg Base64");
  }
}

// Przykład użycia
const originalText = "Hello, World!";
const encoded = encodeToBase64(originalText);
console.log("Zakodowane:", encoded);  // SGVsbG8sIFdvcmxkIQ==

try {
  const decoded = decodeFromBase64(encoded);
  console.log("Odkodowane:", decoded);  // Hello, World!
} catch (error) {
  console.error(error.message);
}
# Kodowanie/Dekodowanie Base64 w Pythonie
import base64

def encode_to_base64(text):
    # Konwertuj ciąg na bajty, a następnie zakoduj
    text_bytes = text.encode('utf-8')
    base64_bytes = base64.b64encode(text_bytes)
    return base64_bytes.decode('utf-8')

def decode_from_base64(base64_string):
    try:
        # Konwertuj ciąg base64 na bajty, a następnie dekoduj
        base64_bytes = base64_string.encode('utf-8')
        text_bytes = base64.b64decode(base64_bytes)
        return text_bytes.decode('utf-8')
    except Exception as e:
        raise ValueError(f"Nieprawidłowy ciąg Base64: {e}")

# Przykład użycia
original_text = "Hello, World!"
encoded = encode_to_base64(original_text)
print(f"Zakodowane: {encoded}")  # SGVsbG8sIFdvcmxkIQ==

try:
    decoded = decode_from_base64(encoded)
    print(f"Odkodowane: {decoded}")  # Hello, World!
except ValueError as e:
    print(e)
// Kodowanie/Dekodowanie Base64 w Javie
import java.util.Base64;
import java.nio.charset.StandardCharsets;

public class Base64Example {
    public static String encodeToBase64(String text) {
        byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
        byte[] encodedBytes = Base64.getEncoder().encode(textBytes);
        return new String(encodedBytes, StandardCharsets.UTF_8);
    }
    
    public static String decodeFromBase64(String base64String) {
        try {
            byte[] base64Bytes = base64String.getBytes(StandardCharsets.UTF_8);
            byte[] decodedBytes = Base64.getDecoder().decode(base64Bytes);
            return new String(decodedBytes, StandardCharsets.UTF_8);
        } catch (IllegalArgumentException e) {
            throw new IllegalArgumentException("Nieprawidłowy ciąg Base64: " + e.getMessage());
        }
    }
    
    public static void main(String[] args) {
        String originalText = "Hello, World!";
        String encoded = encodeToBase64(originalText);
        System.out.println("Zakodowane: " + encoded);  // SGVsbG8sIFdvcmxkIQ==
        
        try {
            String decoded = decodeFromBase64(encoded);
            System.out.println("Odkodowane: " + decoded);  // Hello, World!
        } catch (IllegalArgumentException e) {
            System.err.println(e.getMessage());
        }
    }
}
<?php
// Kodowanie/Dekodowanie Base64 w PHP
function encodeToBase64($text) {
    return base64_encode($text);
}

function decodeFromBase64($base64String) {
    $decoded = base64_decode($base64String, true);
    if ($decoded === false) {
        throw new Exception("Nieprawidłowy ciąg Base64");
    }
    return $decoded;
}

// Przykład użycia
$originalText = "Hello, World!";
$encoded = encodeToBase64($originalText);
echo "Zakodowane: " . $encoded . "\n";  // SGVsbG8sIFdvcmxkIQ==

try {
    $decoded = decodeFromBase64($encoded);
    echo "Odkodowane: " . $decoded . "\n";  // Hello, World!
} catch (Exception $e) {
    echo "Błąd: " . $e->getMessage() . "\n";
}
?>
// Kodowanie/Dekodowanie Base64 w C#
using System;
using System.Text;

class Base64Example
{
    public static string EncodeToBase64(string text)
    {
        byte[] textBytes = Encoding.UTF8.GetBytes(text);
        return Convert.ToBase64String(textBytes);
    }
    
    public static string DecodeFromBase64(string base64String)
    {
        try
        {
            byte[] base64Bytes = Convert.FromBase64String(base64String);
            return Encoding.UTF8.GetString(base64Bytes);
        }
        catch (FormatException)
        {
            throw new FormatException("Nieprawidłowy ciąg Base64");
        }
    }
    
    static void Main()
    {
        string originalText = "Hello, World!";
        string encoded = EncodeToBase64(originalText);
        Console.WriteLine($"Zakodowane: {encoded}");  // SGVsbG8sIFdvcmxkIQ==
        
        try
        {
            string decoded = DecodeFromBase64(encoded);
            Console.WriteLine($"Odkodowane: {decoded}");  // Hello, World!
        }
        catch (FormatException e)
        {
            Console.WriteLine($"Błąd: {e.Message}");
        }
    }
}
# Kodowanie/Dekodowanie Base64 w Rubym
require 'base64'

def encode_to_base64(text)
  Base64.strict_encode64(text)
end

def decode_from_base64(base64_string)
  begin
    Base64.strict_decode64(base64_string)
  rescue ArgumentError => e
    raise "Nieprawidłowy ciąg Base64: #{e.message}"
  end
end

# Przykład użycia
original_text = "Hello, World!"
encoded = encode_to_base64(original_text)
puts "Zakodowane: #{encoded}"  # SGVsbG8sIFdvcmxkIQ==

begin
  decoded = decode_from_base64(encoded)
  puts "Odkodowane: #{decoded}"  # Hello, World!
rescue StandardError => e
  puts "Błąd: #{e.message}"
end
// Kodowanie/Dekodowanie Base64 w Go
package main

import (
    "encoding/base64"
    "fmt"
)

func encodeToBase64(text string) string {
    return base64.StdEncoding.EncodeToString([]byte(text))
}

func decodeFromBase64(base64String string) (string, error) {
    bytes, err := base64.StdEncoding.DecodeString(base64String)
    if err != nil {
        return "", fmt.Errorf("nieprawidłowy ciąg Base64: %v", err)
    }
    return string(bytes), nil
}

func main() {
    originalText := "Hello, World!"
    encoded := encodeToBase64(originalText)
    fmt.Println("Zakodowane:", encoded)  // SGVsbG8sIFdvcmxkIQ==
    
    decoded, err := decodeFromBase64(encoded)
    if err != nil {
        fmt.Println("Błąd:", err)
    } else {
        fmt.Println("Odkodowane:", decoded)  // Hello, World!
    }
}
// Kodowanie/Dekodowanie Base64 w Swift
import Foundation

func encodeToBase64(_ text: String) -> String? {
    if let data = text.data(using: .utf8) {
        return data.base64EncodedString()
    }
    return nil
}

func decodeFromBase64(_ base64String: String) -> String? {
    if let data = Data(base64Encoded: base64String) {
        return String(data: data, encoding: .utf8)
    }
    return nil
}

// Przykład użycia
let originalText = "Hello, World!"
if let encoded = encodeToBase64(originalText) {
    print("Zakodowane: \(encoded)")  // SGVsbG8sIFdvcmxkIQ==
    
    if let decoded = decodeFromBase64(encoded) {
        print("Odkodowane: \(decoded)")  // Hello, World!
    } else {
        print("Błąd: Nie można dekodować ciągu Base64")
    }
} else {
    print("Błąd: Nie można zakodować tekstu")
}
' Kodowanie/Dekodowanie Base64 w Excel VBA
' Uwaga: To wymaga odniesienia do Microsoft XML, v6.0
Function EncodeToBase64(text As String) As String
    Dim xmlObj As Object
    Set xmlObj = CreateObject("MSXML2.DOMDocument")
    
    Dim xmlNode As Object
    Set xmlNode = xmlObj.createElement("b64")
    
    xmlNode.DataType = "bin.base64"
    xmlNode.nodeTypedValue = StrConv(text, vbFromUnicode)
    
    EncodeToBase64 = xmlNode.text
    
    Set xmlNode = Nothing
    Set xmlObj = Nothing
End Function

Function DecodeFromBase64(base64String As String) As String
    On Error GoTo ErrorHandler
    
    Dim xmlObj As Object
    Set xmlObj = CreateObject("MSXML2.DOMDocument")
    
    Dim xmlNode As Object
    Set xmlNode = xmlObj.createElement("b64")
    
    xmlNode.DataType = "bin.base64"
    xmlNode.text = base64String
    
    DecodeFromBase64 = StrConv(xmlNode.nodeTypedValue, vbUnicode)
    
    Set xmlNode = Nothing
    Set xmlObj = Nothing
    Exit Function
    
ErrorHandler:
    DecodeFromBase64 = "Błąd: Nieprawidłowy ciąg Base64"
End Function

' Użycie w arkuszu:
' =EncodeToBase64("Hello, World!")
' =DecodeFromBase64("SGVsbG8sIFdvcmxkIQ==")
# Kodowanie/Dekodowanie Base64 w R
# Wymaga pakietu 'base64enc'
# install.packages("base64enc")
library(base64enc)

encode_to_base64 <- function(text) {
  # Konwertuj tekst na bajty, a następnie zakoduj
  text_raw <- charToRaw(text)
  base64_encoded <- base64encode(text_raw)
  return(rawToChar(base64_encoded))
}

decode_from_base64 <- function(base64_string) {
  tryCatch({
    # Konwertuj ciąg base64 na bajty, a następnie dekoduj
    base64_raw <- charToRaw(base64_string)
    decoded_raw <- base64decode(base64_raw)
    return(rawToChar(decoded_raw))
  }, error = function(e) {
    stop(paste("Nieprawidłowy ciąg Base64:", e$message))
  })
}

# Przykład użycia
original_text <- "Hello, World!"
encoded <- encode_to_base64(original_text)
cat("Zakodowane:", encoded, "\n")  # SGVsbG8sIFdvcmxkIQ==

tryCatch({
  decoded <- decode_from_base64(encoded)
  cat("Odkodowane:", decoded, "\n")  # Hello, World!
}, error = function(e) {
  cat("Błąd:", e$message, "\n")
})
% Kodowanie/Dekodowanie Base64 w MATLAB
function demo_base64()
    originalText = 'Hello, World!';
    
    % Kodowanie
    encoded = encode_to_base64(originalText);
    fprintf('Zakodowane: %s\n', encoded);  % SGVsbG8sIFdvcmxkIQ==
    
    % Dekodowanie
    try
        decoded = decode_from_base64(encoded);
        fprintf('Odkodowane: %s\n', decoded);  % Hello, World!
    catch e
        fprintf('Błąd: %s\n', e.message);
    end
end

function encoded = encode_to_base64(text)
    % Konwertuj tekst na tablicę uint8 i zakoduj
    bytes = uint8(text);
    encoded = base64encode(bytes);
end

function decoded = decode_from_base64(base64String)
    try
        % Dekoduj ciąg base64 na tablicę uint8
        bytes = base64decode(base64String);
        decoded = char(bytes);
    catch
        error('Nieprawidłowy ciąg Base64');
    end
end
// Kodowanie/Dekodowanie Base64 w C przy użyciu OpenSSL
#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <stdint.h>

char* encode_to_base64(const char* input) {
    BIO *bio, *b64;
    BUF_MEM *bufferPtr;
    
    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);
    
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
    BIO_write(bio, input, strlen(input));
    BIO_flush(bio);
    BIO_get_mem_ptr(bio, &bufferPtr);
    
    char* result = (char*)malloc(bufferPtr->length + 1);
    memcpy(result, bufferPtr->data, bufferPtr->length);
    result[bufferPtr->length] = '\0';
    
    BIO_free_all(bio);
    
    return result;
}

char* decode_from_base64(const char* input) {
    BIO *bio, *b64;
    size_t length = strlen(input);
    char* buffer = (char*)malloc(length);
    
    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new_mem_buf(input, -1);
    bio = BIO_push(b64, bio);
    
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
    int decoded_length = BIO_read(bio, buffer, length);
    
    if (decoded_length <= 0) {
        free(buffer);
        BIO_free_all(bio);
        return NULL; // Nieprawidłowy ciąg Base64
    }
    
    buffer[decoded_length] = '\0';
    
    BIO_free_all(bio);
    
    return buffer;
}

int main() {
    const char* original_text = "Hello, World!";
    
    char* encoded = encode_to_base64(original_text);
    printf("Zakodowane: %s\n", encoded);  // SGVsbG8sIFdvcmxkIQ==
    
    char* decoded = decode_from_base64(encoded);
    if (decoded) {
        printf("Odkodowane: %s\n", decoded);  // Hello, World!
        free(decoded);
    } else {
        printf("Błąd: Nieprawidłowy ciąg Base64\n");
    }
    
    free(encoded);
    
    return 0;
}
// Kodowanie/Dekodowanie Base64 w Rust
use base64::{encode, decode};
use std::str;

fn encode_to_base64(text: &str) -> String {
    encode(text)
}

fn decode_from_base64(base64_string: &str) -> Result<String, String> {
    match decode(base64_string) {
        Ok(bytes) => {
            match str::from_utf8(&bytes) {
                Ok(text) => Ok(text.to_string()),
                Err(e) => Err(format!("Nieprawidłowa sekwencja UTF-8: {}", e))
            }
        },
        Err(e) => Err(format!("Nieprawidłowy ciąg Base64: {}", e))
    }
}

fn main() {
    let original_text = "Hello, World!";
    let encoded = encode_to_base64(original_text);
    println!("Zakodowane: {}", encoded);  // SGVsbG8sIFdvcmxkIQ==
    
    match decode_from_base64(&encoded) {
        Ok(decoded) => println!("Odkodowane: {}", decoded),  // Hello, World!
        Err(e) => println!("Błąd: {}", e)
    }
}

Przypadki brzegowe i uwagi

Podczas pracy z kodowaniem i dekodowaniem Base64, zwróć uwagę na te ważne uwagi:

  1. Znaki Unicode i nie-ASCII: Przy kodowaniu tekstu z nie-ASCII, upewnij się, że używasz odpowiedniego kodowania znaków (zwykle UTF-8) przed kodowaniem Base64.

  2. Padding: Standardowe Base64 używa paddingu z znakami "=" w celu zapewnienia, że długość wyjścia jest wielokrotnością 4. Niektóre implementacje pozwalają na pominięcie paddingu, co może powodować problemy z kompatybilnością.

  3. Złamania linii: Tradycyjne implementacje Base64 wstawiają złamania linii (zwykle co 76 znaków) dla czytelności, ale nowoczesne aplikacje często je pomijają.

  4. Bezpieczne Base64 w URL: Standardowe Base64 używa znaków "+" i "/", które mają specjalne znaczenia w adresach URL. W kontekście URL użyj bezpiecznego Base64, które zastępuje te znaki "-" i "_".

  5. Białe znaki: Podczas dekodowania niektóre implementacje są tolerancyjne i ignorują białe znaki, podczas gdy inne wymagają dokładnego wejścia.

  6. Wzrost rozmiaru: Kodowanie Base64 zwiększa rozmiar danych o około 33% (4 bajty wyjściowe na każde 3 bajty wejściowe).

  7. Wydajność: Kodowanie/dekodowanie Base64 może być obciążające obliczeniowo dla bardzo dużych danych. Rozważ podejścia strumieniowe dla dużych plików.

Referencje

  1. RFC 4648 - Kodowania danych Base16, Base32 i Base64
  2. RFC 2045 - MIME część pierwsza: Format ciał wiadomości internetowych
  3. MDN Web Docs: Kodowanie i dekodowanie Base64
  4. Base64 - Wikipedia
  5. MIME - Wikipedia
Feedback