# Número màgic (informàtica)

En informàtica, un número màgic o magic number, identifica una cadena de text, utilitzada per a diferents finalitats, o un nombre al qual no s'associa un significat explícit, però el valor del qual és essencial per al funcionament del codi. Per tant, aquest últim cas no es recomana mitjançant les millors pràctiques de programació (anti-patró).

## Constants numèriques sense nom

El terme número màgic o constant màgica es refereix a l'antipatró d'utilitzar números directament al codi font. Això s'ha conegut com un trencament d'una de les regles de programació més antigues, que es remunta als manuals COBOL, FORTRAN i PL/1 dels anys 60. L'ús de números màgics sense nom en el codi enfosquia la intenció dels desenvolupadors a l'hora d'escollir aquest número, augmenta les oportunitats d'errors subtils (per exemple, cada dígit és correcte a 3.14159265358979323846 i això és igual a 3.14159?) i dificulta el programa. per adaptar i ampliar en el futur. La substitució de tots els números màgics significatius per constants anomenades fa que els programes siguin més fàcils de llegir, comprendre i mantenir.

## Orígens

Els "Magic numbers" com indicadors de format es van utilitzar per primera vegada al codi font Unix de la versió 7 inicial. Unix es va portar a un dels primers DEC PDP-11 /20, que no tenia protecció de memòria. Així que les primeres versions d'Unix utilitzaven el model de referència de memòria reubicable. Les versions Unix anteriors a la sisena edició van llegir un fitxer executable a la memòria i van saltar a la primera adreça de memòria baixa del programa, l'adreça relativa zero. Amb el desenvolupament de versions paginades d'Unix, es va crear una capçalera per descriure els components de la imatge executable. A més, es va inserir una instrucció de branca com a primera paraula de la capçalera per saltar-la i iniciar el programa. D'aquesta manera, un programa es podria executar en el mode de referència de memòria reubicable anterior (regular) o en mode paginat. A mesura que es van desenvolupar més formats executables, es van afegir noves constants augmentant el desplaçament de la branca.
Els noms escollits per ser significatius en el context del programa poden donar lloc a un codi més fàcil d'entendre per un responsable que no és l'autor original (o fins i tot per l'autor original després d'un període). Un exemple d'una constant amb un nom no informatiu és int SIXTEEN = 16, mentre que int NUMBER_OF_BITS = 16 és més descriptiu.
Els problemes associats als "números" màgics descrits anteriorment no es limiten als tipus numèrics i el terme també s'aplica a altres tipus de dades on declarar una constant anomenada seria més flexible i comunicatiu. Per tant, declarar const string testUserName = "John" és millor que diverses ocurrències del "valor màgic" "John" en un conjunt de proves.

## Característiques

Primerament indicaria:
* una seqüència de bits, normalment col·locada abans de la seqüència de dades, que serveix per definir el format en què s'emmagatzemen les dades.
* un número o cadena repetida diverses vegades al codi font d'un programa que no té cap significat explícit associat.
El segon ús del terme és purament despectiu: inserir constants al codi (ja siguin numèriques o de cadena) sense donar-los un significat explícit condueix a un codi difícilment llegible. És una bona idea donar a aquestes constants un nom i un significat explícit, possiblement al començament del codi, i utilitzar sempre aquesta definició. Els problemes relacionats amb l'ús dels números màgics són:
* dificultats per llegir i, per tant, per mantenir el codi: una cadena o un enter inserit al programa sense denominació parlant, són difícils d'interpretar.
* possible inconsistència del codi: si la constant es repeteix n vegades, la seva variació requereix n substitucions. Si un d'ells salta dona lloc a errors.

## Ús

Els números màgics es van emprar en entorns Unix per identificar el format dels fitxers binaris i gestionar les dades a la memòria. Avui en dia, la majoria dels formats de fitxer tenen un nombre màgic, que consisteix en un nombre variable de bytes (normalment de 2 a 10). També s'utilitza en protocols de xarxa, per identificar el protocol o errors en la transmissió de dades.
Tot i que gairebé tots els formats de fitxer estan identificats per un número màgic, Microsoft ha decidit adoptar un nou identificador des de les primeres versions del seu sistema operatiu DOS: l'extensió. Encara avui, els sistemes operatius de Microsoft no utilitzen el número màgic per deduir el format de pertinença d'un fitxer determinat, sinó precisament les extensions. Tanmateix, els números màgics poden ser útils per definir la versió.

## Exemples

Cal tenir en compte que aquests marcadors són realment útils per al programari de recuperació de dades (per exemple TestDisk, per citar-ne un) ja que a través d'ells són capaços d'identificar la presència d'un determinat tipus de fitxer, o estructura, encara que el sistema de fitxers estigui danyat.
Es poden enumerar entre altri:
* Els fitxers de classe Java compilats (codi de bytes) i els binaris Mach-O comencen amb hex CAFEBABE. Quan es comprimeixen amb Pack200, els bytes es canvien a CAFED00D.
* Els fitxers d'imatge GIF tenen el codi ASCII per a "GIF89a" (47 49 46 38 39 61) o "GIF87a" (47 49 46 38 37 61)
* Els fitxers d'imatge JPEG comencen amb FF D8i acaben amb FF D9. Els fitxers JPEG/ JFIF contenen el codi ASCII de "JFIF" (4A 46 49 46) com a cadena acabada nul·la. Els fitxers JPEG/ Exif contenen el codi ASCII per a "Exif" (45 78 69 66) també com una cadena acabada nul·la, seguida de més metadades sobre el fitxer.
* Els fitxers d'imatge PNG comencen amb una signatura de 8 bytes que identifica el fitxer com a fitxer PNG i permet detectar problemes habituals de transferència de fitxers: \211 P N G \r \n \032 \n(89 50 4E 47 0D 0A 1A 0A). Aquesta signatura conté diversos caràcters de nova línia per permetre detectar conversions de nova línia automatitzades no justificades, com ara transferir el fitxer mitjançant FTP amb el mode de transferència ASCII en comptes del mode binari .
* Standard MIDI arxius d'àudio tenen el ASCII codi per "mthd" (M IDI T acumular h ea d er, 4D 54 68 64) seguit per més de metadades.
* Els scripts Unix o Linux poden començar amb un "shebang" (#!, 23 21) seguit del camí a un intèrpret, si és probable que l'intèrpret sigui diferent d'aquell des del qual s'ha invocat un script.
* Els executables ELF comencen amb7F E L F
* Els fitxers i programes PostScript comencen amb "%!" (25 21).
* Els fitxers PDF comencen amb "%PDF" (hexadecimal 25 50 44 46).
* Els fitxers executables DOS MZ i capçalera EXE dels fitxers Microsoft Windows PE (Executable portàtil) comencen amb els caràcters "MZ" (4D 5A), les inicials del dissenyador del format de fitxer, Mark Zbikowski. La definició permet també el poc comú "ZM" (5A 4D) per a dosZMXP, un EXE no PE.
* El format de superbloc de Berkeley Fast File System s'identifica com a qualsevol 19 54 01 19o en 01 19 54funció de la versió; tots dos representen l'aniversari de l'autor, Marshall Kirk McKusick .
* El registre d'arrencada mestre dels dispositius d'emmagatzematge d'arrencada de gairebé tots els compatibles amb IA-32 IBM PC té un codi dels 55 AAdos últims bytes.
* Els executables per als sistemes de videojocs portàtils Game Boy i Game Boy Advance tenen un nombre màgic de 48 o 156 bytes, respectivament, en un punt fix de la capçalera. Aquest número màgic codifica un mapa de bits del logotip de Nintendo .
* Els fitxers Hunk executables del programari Amiga que s'executen a les màquines Amiga classic 68000 van començar amb el número hexadecimal $000003f3, sobrenomenat "Magic Cookie".
* A l'Amiga, l'única adreça absoluta del sistema és hex $0000 0004 (ubicació de memòria 4), que conté la ubicació inicial anomenada SysBase, un punter a exec.library, l'anomenat nucli d'Amiga.
* Els fitxers PEF, utilitzats pels executables clàssics de Mac OS i BeOS per a PowerPC, contenen el codi ASCII de "Joy!" (4A 6F 79 21) com a prefix.
* Els fitxers TIFF comencen amb qualsevol IIo MMseguit de 42 com un nombre enter de dos bytes en l'ordre de bytes endians petits o grans . IIÉs per Intel, que utilitza poc endian ordre de bytes, de manera que el nombre màgic és 49 49 2A 00. MMés per a Motorola, que utilitza l'ordre de bytes big endian, de manera que el número màgic és 4D 4D 00 2A.
* Unicode arxius de text codificats en UTF-16 sovint comencen amb el byte marca d'ordre per detectar endianness (FE FFper big endian i FF FEper poc endian). I a Microsoft Windows, els fitxers de text UTF-8 sovint comencen amb la codificació UTF-8 del mateix caràcter, EF BB BF.
* Els fitxers de BCcodi de bits LLVM comencen amb (0x42, 0x43)
* Els fitxers WAD comencen amb IWADo PWAD(per a Doom), WAD2(per a Quake) i WAD3(per a Half-Life).
* Els fitxers de Microsoft Compound File Binary Format (conegut principalment com un dels formats més antics dels documents de Microsoft Office) comencen amb D0 CF 11 E0, que suggereix visualment la paraula "DOCFILE0".
* Les capçaleres dels fitxers ZIP comencen amb "PK" (50 4B), les inicials de Phil Katz, autor de la utilitat de compressió de DOS PKZIP .
* Les capçaleres dels fitxers 7z comencen amb "7z" (número màgic complet: 37 7A BC AF 27 1C).
* Els fitxers d'imatge GIF, per exemple, sempre comencen amb la cadena ASCII GIF87a o GIF89a que defineix l'estàndard al qual s'adhereix el fitxer.
* Tots els fitxers ZIP PK (en hexadecimal 50 4B), a partir de les inicials del nom del creador Phil Katz.
* Els scripts Unix o Linux poden començar amb els dos caràcters #!, és a dir, 23 21 en hexadecimal, seguit del camí d'un intèrpret, si l'intèrpret és diferent d'aquell des del qual s'ha invocat l'script.
* Els executables ELF comencen amb 7F 45 4C 46 (els tres últims bytes d'aquest nombre màgic formen la paraula ELF)
* Els fitxers PDF comencen amb "% PDF" (en hexadecimal 25 50 44 46).
* Si un dispositiu d'emmagatzematge conté el registre d'arrencada mestre, aleshores els dos últims bytes del MBR contenen el número màgic 55 AA .
* Els fitxers de text codificats Unicode UTF-16 sovint comencen amb un marcador que identifica el seu ordre de bytes: FE FF per als grans endians i FF FE per als petits

## "Magic Numbers" típics

* Shebang
* XYZZY (magic word)
* Hexspeak
* Canary words

## Xarxes

En l'àmbit informàtic s'utilitza per dividir xarxes: en particular permet trobar la següent xarxa i, per tant, identificar l'emissió de l'actual. Es calcula amb la fórmula següent: MN = 2 ^ n on n és el nombre de bits establert a 0 del byte crític de la màscara de subxarxa (és a dir, els bits reservats per a l'amfitrió).
Exemple:
* Xarxa 1 = 172.22.20.0
* Màscara de subxarxa = 255.255.255.224
* Màscara de subxarxa (binari) = 11111111.11111111.11111111.11 1 00000
* byte crític = 2 ^ 5
* Nombre màgic = 2 ^ 5 = 32
* Xarxa següent = 172.22.20. (0 + 32) = 172.22.20.32

## Referències

* 1 2 3 4 «language agnostic - What is a magic number, and why is it bad?».
* ↑ Martin, Robert C. «Chapter 17: Smells and Heuristics - G25 Replace Magic Numbers with Named Constants». A: Clean Code - A handbook of agile software craftsmanship. Boston: Prentice Hall, 2009, p. 300. ISBN 978-0-13-235088-4.
* ↑ Martin, Robert C. «Chapter 17: Smells and Heuristics - G16 Obscured Intent». A: Clean Code - A handbook of agile software craftsmanship. Boston: Prentice Hall, 2009, p. 295. ISBN 978-0-13-235088-4.
* ↑ Maguire, James. «Bjarne Stroustrup on Educating Software Developers». Datamation.com, 09-12-2008. Arxivat de l'original el 23 juny 2018.
* ↑ Vogel, Jeff. «Six ways to write more comprehensible code». IBM Developer, 29-05-2007.
* ↑ «Odd Comments and Strange Doings in Unix». Bell Labs, 22-06-2002. Arxivat de l'original el 2006-11-04.
* ↑ Personal communication with Dennis M. Ritchie.
* ↑ Martin, Robert C. «Chapter 17: Smells and Heuristics - G25 Replace Magic Numbers with Named Constants». A: Clean Code - A handbook of agile software craftsmanship. Boston: Prentice Hall, 2009, p. 300. ISBN 978-0-13-235088-4.
* ↑ Kessler, Gary C. «File Signatures», 11-01-2022.
* ↑ Poley, Josh. «Magic Numbers: Integers», 30-09-2009.
* ↑ Mitchell, Bradley. «Magic Numbers in Wireless and Computer Networking» (en italià), 03-10-2019.

## Enllaços externs

* «Magic number» (en rus), 06-09-2018.