Magic number
# Magic number

Un magic number, in informatica, identifica una stringa di testo, utilizzata con differenti finalità, oppure un numero a cui non è associato un significato esplicito, ma il cui valore è essenziale ai fini del funzionamento del codice. Quest'ultimo caso, pertanto, è sconsigliato dalle best practice della programmazione (anti-pattern).

## Caratteristiche

Esso indicherebbe:

* una sequenza di bit, normalmente posta prima della sequenza di dati, che serve per definire il formato in cui i dati sono memorizzati.
* un numero o una stringa ripetuta più volte nel codice sorgente di un programma a cui non è attribuito un significato esplicito.

Il secondo uso del termine è prettamente dispregiativo: inserire nel codice delle costanti (siano esse numeriche o di tipo stringa) senza dare loro un significato esplicito porta ad avere codice poco leggibile. È buona norma dare a tali costanti un nome ed un significato esplicito, possibilmente all'inizio del codice, e utilizzare sempre tale definizione. I problemi legati all'uso di magic number sono:

* difficoltà di lettura e, quindi, di manutenzione del codice: una stringa o un intero inserito all'interno del programma senza una denominazione parlante, sono difficili da interpretare.
* possibile inconsistenza del codice: se la costante è ripetuta n volte, la sua variazione richiede n sostituzioni. Se una di esse salta si dà origine a bug.

## Utilizzo

I magic number sono nati negli ambienti Unix per identificare il formato dei file binari e per la gestione dei dati nella memoria. Oggi la maggior parte dei formati del file hanno un magic number, costituito da un numero di byte variabile (solitamente da 2 a 10). Viene anche utilizzato nei protocolli di rete, per identificare il protocollo o errori nella trasmissione dei dati.

Sebbene quasi tutti formati di file siano identificati da un magic number, la Microsoft sin dalle prime versioni del suo sistema operativo DOS ha deciso di adottare un nuovo identificativo: l'estensione. Ancora oggi, i sistemi operativi Microsoft non utilizzano il magic number per dedurre il formato di appartenenza di un determinato file, ma appunto le estensioni. I magic number possono comunque essere utili per definirne la versione.

## Esempi

* I file immagine GIF, per esempio, cominciano sempre con la stringa ASCII GIF87a o GIF89a che definisce lo standard al quale il file aderisce.
* Le classi Java compilate hanno il magic number CAFEBABE, (in esadecimale diventa 43 41 46 45 42 41 42 45).
* I file ZIP cominciano tutti per PK (in esadecimale 50 4B), dalle iniziali del nome dell'ideatore Phil Katz.
* Gli script Unix o Linux possono iniziare con i due caratteri #!, cioè 23 21 in esadecimale, seguiti dalla path di un interpreter, se l'interpreter è diverso da quello da cui è stato invocato lo script.
* Gli eseguibili ELF iniziano con 7F 45 4C 46 (gli ultimi tre byte di questo magic number vanno a formare la parola ELF)
* I file PDF iniziano con "%PDF" (in esadecimale 25 50 44 46).
* Se un dispositivo di memorizzazione contiene Master Boot Record, allora gli ultimi due byte dell'MBR contengono il magic number 55 AA.
* I file di testo Unicode codificati in UTF-16 spesso iniziano con un marcatore che ne identifica l'ordine dei byte: FE FF per i big endian, e FF FE per i little endian.
* ...molti altri

Da notare che questi marcatori sono davvero utili ai software di recupero dei dati (per esempio TestDisk, per citarne uno) in quanto attraverso di essi riescono ad identificare la presenza di un dato tipo di file, o di struttura, anche se il File System è danneggiato.

In ambito informatico viene utilizzato per suddividere le reti: in particolare permette di trovare la rete successiva e quindi di individuare il broadcast dell'attuale. Si calcola con la seguente formula: MN= 2^n dove n è il numero dei bit posti a 0 del byte critico della Subnet Mask (ovvero i bit riservati all'host) Esempio:

* Rete 1= 172.22.20.0
* Subnet mask=255.255.255.224
* Subnet mask (binario)= 11111111.11111111.11111111.11100000
* byte critico = 2^5
* Magic number= 2^5=32
* Rete successiva= 172.22.20.(0+32)=172.22.20.32
