base64, tipi di file, codifiche

Possiamo logicamente dividere i file in binary e text.

Su wikipedia si trova la definizione di text file e binary files.

TEXT FILES
I file di testo, detti anche textfile, sono un tipo di file pensato per memorizzare e esporre del testo leggibile dagli esseri umani.
“Text file” si riferisce al contenitore, mentre “plain text” si riferisce al tipo di contenuto, per cui potremmo avere file di testo che contengono “altro” (dove con altro intendiamo qualcosa di non direttamente interpretabile da un essere umano).

BINARY FILES
I file binari sono un tipo di file pensato per memorizzare un contenuto letto e interpretato da altri programmi. Sono in generale delle seguenze di bytes, ovvero bit raggruppati in gruppi da 8. Tipici esempi sono il programma compilato, l'immagine jpeg, il documento word etc.

UNIAMO I CONCETTI
In realtà binary e text per il computer sono la stessa cosa: Semplici dati memorizzati in sequenze di bit. Tutto sta nell'interpretazione che vogliamo dare a queste sequenze.

Se vai ad aprire un file binario, come un mp3, con un editor testuale (tipo vi), quasi nulla avrà senso perchè l'editor cercherà di tradurre i bit in testo e, per molti bit ci riuscirà presentando cose senza senso, per molti altri invece neanche troverà un corrispettivo.

Altro esempio, andiamo ad aprire un file di testo utf-8 con un editor che pensa sia "pure ascii". Tutti i caratteri al di fuori dei 128 che l'ascii riconosce non verranno riprodotti correttamente. Per esempio la ì è codificata in utf-8 come 11000011 11000011(oppure C3 AC in esadecimale), quando l'ascii trova queste sequenze non sa come interpretarle (e visto che non sa che utf8 usa un numero di byte variabili per un singolo carattere, in questo caso 2 byte, pensa addirittura che siano 2 caratteri distinti) e presenta a testo delle schifezze.
Un file binario può contenere potenzialmente qualsiasi sequenza di uni e zeri possibile: Per cui anche aprendolo con un editor di test che utilizzi una codifica molto ricca, che quindi riconosca moltissime sequenze possibili, avremo sempre come risultato qualche cosa di non riconosciuto (e ovviamente nessun senso anche su ciò che viene riconosciuto).

Possiamo  vedere il contenuto di un file binario rappresentando ciascun byte come 2 cifre esadecimali. E' solo una rappresentazione che ci fornisce un qualcosa di più facilmente comprensibile rispetto alla sequenza di bit. Inoltre tutti i possibili 256 valori che può assumere un byte sono rappresentati da 2 cifra esadecimali (16*16 = 2^8).

Alcuni editor di testo potrebbero avere una modalità hex che cerchi di determinare con tecnice euristiche se si tratta di un file binario o di testo e poi comportarsi di consegueza. E' anche abbastanza tipico avere degli editor che fanno la rappresentazione hex e che poi cerchino di convertire questa in testo laddove riescono a dare un senso (di solito cercando le codifiche ascii).

Uno di questi programmi è ghex/ghex2 per gnome che fa anche la conversione automatica hex-to-ascii.

Hex (BASE16)è quindi un modo di rappresentare i file binari in un formato comprensibile, utilizzando 2 caratteri per ogni byte.
Un'altro modo pià efficente è (BASE64) che utilizza 4 caratteri per ogni 3 bytes.

Quindi, base64 non è un algoritmo di crittazione ma solo un modo di rappresentare informazioni binarie con caratteri aflanumerici.

Perchè c'è la necessità di avere questo tipo di rappresentazione alfanumerica che comunque quasi mai ha un senso per l'uomo e che il computer deve riconvertire quando invece sarebbe gia comprensibile per lui come binario?

Tutto questo penso abbia a che fare con le reti e con il fatto che molto raramente (in passato) effettuavi uno streaming diretto di bit e byte sul cavo in maniera grezza (raw). Questo perchè alcuni protocolli possono interpretare le sequenze di bit come comandi di controllo (come  un modem per esempio) oppure ftp (questo è l'esempio più classico) potrebbe pensare che stai dando una speciale combinazione di caratteri per trasformare il carattere termina riga (linux e windows usano 2 terminatori leggermente diversi e ftp li covnertiva automaticamente).

Quindi per evitare che i protocolli  interpretino erroneamente i dati che gli stiamo inviando, mandiamo tutto codificato in base64 che usa un subset di caratteri ascii che siam sicuri che venga correttamente interpretato (a-z, A-Z, 0-9, / e +,il carattere = ha un significato speciale).

Per esempio

Voglio mandare questo file a un amico

Se glielo mando direttamente in ascii o utf-8 (in questo caso sono uguali), gli manderò qualcosa del tipo

109 105 97 111 123

(questi numeri decimali sono il corrispondente dei singoli caratteri in ascii, m = codice ascii 109)

Effettuo il base64 encode su questo contenuto

Ricodifico in ascii questo, che sarà un qualcosa del tipo

98 87 108 104 98 51 115 75

In questo modo, sebbene il file sia diventato pià grosso siam sicuri verrà interpretato correttamente dal protocollo che abbiamo deciso di usare per la comunicazione.

Curiosità SERVER WEB

Chiunque abbia mai gestito un server web tipo apache/nginx avrà sicuramente visto nei log cose di questo tipo

GET /file.php?qualcosa=\x90\x70p\xc6Z\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\xd2\xdc\x

(Per fare le conversioni mi aiuto con questo convertitore http://home.paulschou.net/tools/xlate/)

Allora quando mettiamo una \x in generale significa che stiamo parlando di esadecimale

\xHH -> rappresentazione esadecimale di un raw byte del valore HH. Ricordiamo come con 2 caratteri esadecimali prossiamo rappresentare ogni possibile byte. Di solito si usa questa sequenza quando si vuole rappresentare un byte che non ha associato alcun carattere ascii, altrimenti scriveremmo direttamente l'ascii.

\x99 - 99 è hex, in binario 10011001 e questo non ha alcun corrispondente ascii.

\x99P – solo i primi 2 numeri sono hex, quello che segue è un normale carattere ascii, quindi per rappresentarlo in hex lo convertiamo

P -> Codice ascii 80 -> in binario 01010000, in hex 50

Quindi scrivere \x99P è come scrivere \x99\x50

Quindi la stringa x99\x99P possiamo rappresentarla in hex come

99 99 59

Non ho ovviamente la minima idea di che significato questa possa avere per il mio server.

Print Friendly, PDF & Email