Base64 è un sistema di codifica che consente la traduzione di dati binari (contenenti sequenze di 8 bit) in stringhe di testo ASCII, rappresentando i dati sulla base di 64 caratteri ASCII diversi.
Viene usato principalmente come codifica di dati binari nelle e-mail, per convertire i dati nel formato ASCII.
L'algoritmo
L'algoritmo che effettua la conversione suddivide il file in gruppi da 6 bit, i quali possono quindi contenere valori da 0 a 63. Ogni possibile valore viene convertito in un carattere ASCII secondo la seguente tabella:
Valore
|
ASCII
|
0
|
A
|
1
|
B
|
2
|
C
|
3
|
D
|
4
|
E
|
5
|
F
|
6
|
G
|
7
|
H
|
8
|
I
|
9
|
J
|
10
|
K
|
11
|
L
|
12
|
M
|
13
|
N
|
14
|
O
|
15
|
P
|
Valore
|
ASCII
|
16
|
Q
|
17
|
R
|
18
|
S
|
19
|
T
|
20
|
U
|
21
|
V
|
22
|
W
|
23
|
X
|
24
|
Y
|
25
|
Z
|
26
|
a
|
27
|
b
|
28
|
c
|
29
|
d
|
30
|
e
|
31
|
f
|
Valore
|
ASCII
|
32
|
g
|
33
|
h
|
34
|
i
|
35
|
j
|
36
|
k
|
37
|
l
|
38
|
m
|
39
|
n
|
40
|
o
|
41
|
p
|
42
|
q
|
43
|
r
|
44
|
s
|
45
|
t
|
46
|
u
|
47
|
v
|
Valore
|
ASCII
|
48
|
w
|
49
|
x
|
50
|
y
|
51
|
z
|
52
|
0
|
53
|
1
|
54
|
2
|
55
|
3
|
56
|
4
|
57
|
5
|
58
|
6
|
59
|
7
|
60
|
8
|
61
|
9
|
62
|
+
|
63
|
/
|
Il set di 64 caratteri scelto per rappresentare i 64 valori (0-63) varia a seconda dell'implementazione scelta. L'obiettivo solitamente è di scegliere 64 caratteri che siano comuni alla maggior parte delle codifiche e che siano anche stampabili.
Le altre varianti, solitamente derivate dal Base64, condividono queste proprietà ma differiscono nella scelta degli ultimi due caratteri; per esempio la variante URL e file name safe (RFC 4648/Base64URL), usa "-" e "_".
L'algoritmo causa un aumento delle dimensioni dei dati del 33%, poiché ogni gruppo di 3 byte viene convertito in 4 caratteri. Questo supponendo che per rappresentare un carattere si utilizzi un intero byte.
Se per rappresentare i caratteri ASCII si usassero 7 bit (che sarebbero sufficienti) e non 8, l'aumento di dimensioni sarebbe solo del 17%. Poiché però per rappresentare i caratteri ASCII si usano convenzionalmente 8 bit (7 per il carattere, lasciando il restante bit nullo), allora si ottiene l'aumento delle dimensioni descritto poco fa.
Esempio di codifica
Dati 3 byte che contengono i valori A, B, C, partendo dalla loro rappresentazione binaria, applichiamo l'algoritmo:
Rappresentazione ASCII: A B C
| | |
Rappresentazione binaria: 01000001 01000010 01000011
/ \ / \ / \
Suddivisione in gruppi da 6 bit: 010000 01 0100 0010 01 000011
|----| \------/ \------/ |----|
I 4 valori dedotti: 010000 010100 001001 000011
\/ \/ \/ \/
Il valore decimale: 16 20 9 3
| | | |
Il valore codificato: Q U J D
Quindi la sequenza di valori (ABC) viene convertita nella sequenza (QUJD).
Se la lunghezza del messaggio originale non è un multiplo di 3 byte il numero dei bit che costituiscono il risultato non sarà un multiplo di 6. Verranno quindi inseriti bit nulli (0) alla fine (4 o 2), e nel valore codificato vengono aggiunti da 0 a 2 simboli '=' (padding character) sufficienti a raggiungere un multiplo di 4 simboli. Ciascun padding character indica pertanto l'aggiunta di una coppia di bit nulli. Il padding non è comunque indispensabile per la decodifica e alcune implementazioni non lo utilizzano. Il padding è indispensabile solo qualora si vogliano concatenare messaggi codificati.
Quindi, preso un singolo byte di valore (A), esso viene convertito nella sequenza (QQ==), il singolo valore (B) viene convertito in (Qg==), mentre la sequenza (AB) diventa (QUI=).
- Possibile routine di conversione
union conv
{
unsigned int l;
struct bytes
{
char b1;
char b2;
char b3;
char b4;
} b;
};
char convert (char c)
{
if (c == 63)
return 47;
else if (c == 62)
return 43;
else if (c >= 52)
return c - 4;
else if (c >= 26)
return c + 71;
else
return c + 65;
}
unsigned int toBase64(char b1, char b2, char b3)
{
conv src, dest;
src.b.b1 = b3;
src.b.b2 = b2;
src.b.b3 = b1;
src.b.b4 = 0;
//conv.l == b4 b3 b2 b1
dest.b.b1 = convert(src.b.b1 & 0x3f);
src.l = src.l >> 6;
dest.b.b2 = convert(src.b.b1 & 0x3f);
src.l = src.l >> 6;
dest.b.b3 = convert(src.b.b1 & 0x3f);
src.l = src.l >> 6;
dest.b.b4 = convert(src.b.b1 & 0x3f);
return dest.l;
}
Varianti
Esistono varianti di questa codifica, che differiscono principalmente nella scelta dei due caratteri usati per rappresentare i valori 62 e 63 e per il "padding char". In particolare molto usata è la variante che usa i caratteri "-" e "_" come valori 62 e 63 (al posto di "+" e "/") e non usa padding; questa variante è particolarmente utile quando la stringa codificata deve essere usata in una URL o in un filename.
Collegamenti esterni