En programación de computadoras , el término número mágico tiene múltiples significados. Podría referirse a uno o más de los siguientes:
- Valores únicos con significado inexplicable o ocurrencias múltiples que podrían (preferiblemente) reemplazarse con constantes nombradas
- Un valor numérico o de texto constante que se utiliza para identificar un formato de archivo o protocolo; para archivos, consulte Lista de firmas de archivos
- Valores únicos distintivos que es poco probable que se confundan con otros significados (p. Ej., Identificadores únicos globales )
Constantes numéricas sin nombre
El término número mágico o constante mágica se refiere al anti-patrón de usar números directamente en el código fuente. A esto se le ha referido como romper una de las reglas de programación más antiguas, que se remonta a los manuales COBOL , FORTRAN y PL / 1 de la década de 1960. [1] El uso de números mágicos sin nombre en el código oscurece la intención de los desarrolladores al elegir ese número, [2] aumenta las oportunidades de errores sutiles (por ejemplo, ¿todos los dígitos son correctos en 3.14159265358979323846 y esto es igual a 3.14159?) Y lo hace más difícil para que el programa se adapte y amplíe en el futuro. [3] Reemplazar todos los números mágicos significativos con constantes nombradas hace que los programas sean más fáciles de leer, comprender y mantener. [4]
Los nombres elegidos para ser significativos en el contexto del programa pueden resultar en un código que sea más fácil de entender por un mantenedor que no es el autor original (o incluso por el autor original después de un período de tiempo). Un ejemplo de una constante con nombre no informativo es int SIXTEEN = 16
, while int NUMBER_OF_BITS = 16
es más descriptivo.
Los problemas asociados con los 'números' mágicos descritos anteriormente no se limitan a tipos numéricos y el término también se aplica a otros tipos de datos donde declarar una constante nombrada sería más flexible y comunicativo. [1] Por lo tanto, declarar const string testUserName = "John"
es mejor que varias ocurrencias del 'valor mágico' "John"
en una suite de pruebas .
Por ejemplo, si se requiere mezclar aleatoriamente los valores en una matriz que representa un paquete estándar de naipes , este pseudocódigo hace el trabajo usando el algoritmo de reproducción aleatoria de Fisher-Yates :
para yo de 1 a 52 j: = i + randomInt (53 - i) - 1 a.swapEntries (i, j)
donde a
es un objeto de matriz, la función randomInt(x)
elige un número entero aleatorio entre 1 y x , inclusive, e swapEntries(i, j)
intercambia las entradas i- ésima y j- ésima en la matriz. En el ejemplo anterior, 52
es un número mágico. Se considera un mejor estilo de programación escribir lo siguiente:
constante int deckSize: = 52 para i de 1 a deckSize j: = i + randomInt (deckSize + 1 - i) - 1 a.swapEntries (i, j)
Esto es preferible por varias razones:
- Es más fácil de leer y comprender. Un programador que lea el primer ejemplo podría preguntarse: ¿Qué significa el número 52 aquí? ¿Por qué 52? El programador puede inferir el significado después de leer el código detenidamente, pero no es obvio. Los números mágicos se vuelven particularmente confusos cuando el mismo número se usa para diferentes propósitos en una sección de código.
- Es más fácil alterar el valor del número, ya que no está duplicado. Cambiar el valor de un número mágico es propenso a errores, porque el mismo valor a menudo se usa varias veces en diferentes lugares dentro de un programa. Además, cuando dos variables o números semánticamente distintos tienen el mismo valor, ambos pueden editarse juntos accidentalmente. Para modificar el primer ejemplo para barajar una baraja de Tarot , que tiene 78 cartas, un programador podría reemplazar ingenuamente cada instancia de 52 en el programa con 78. Esto causaría dos problemas. Primero, perdería el valor 53 en la segunda línea del ejemplo, lo que haría que el algoritmo fallara de manera sutil. En segundo lugar, es probable que reemplace los caracteres "52" en todas partes, independientemente de si se refieren al tamaño del mazo o a algo completamente diferente, como el número de semanas en un año calendario gregoriano, o más insidiosamente, son parte de un número como "1523", todos los cuales introducirían errores. Por el contrario, cambiar el valor de la
deckSize
variable en el segundo ejemplo sería un cambio simple de una línea. - Fomenta y facilita la documentación. El único lugar donde se declara la variable nombrada es un buen lugar para documentar lo que significa el valor y por qué tiene el valor que tiene. Tiene el mismo valor en una plétora de lugares o bien conduce a los comentarios duplicados (y consiguientes problemas al actualizar algunos, pero faltan algunos) o las hojas sin un lugar donde es tanto naturales para el autor para explicar el valor y es probable que el lector deberá buscar una explicación .
- Las declaraciones de variables de "número mágico" se colocan juntas, generalmente en la parte superior de una función o archivo, lo que facilita su revisión y cambio.
- Facilita la parametrización. Por ejemplo, para generalizar el ejemplo anterior en un procedimiento que baraja una baraja de cualquier número de cartas, sería suficiente convertirlo
deckSize
en un parámetro de ese procedimiento, mientras que el primer ejemplo requeriría varios cambios.
función shuffle ( int deckSize) para i de 1 a deckSize j: = i + randomInt (deckSize + 1 - i) - 1 a.swapEntries (i, j)
- Ayuda a detectar errores tipográficos . El uso de una variable (en lugar de un literal) aprovecha la comprobación de un compilador. Escribir accidentalmente "62" en lugar de "52" pasaría desapercibido, mientras que escribir "
dekSize
" en lugar de "deckSize
" daría como resultado una advertencia del compilador quedekSize
no se declara. - Puede reducir la escritura en algunos IDE . Si un IDE admite la finalización de código , completará la mayor parte del nombre de la variable desde las primeras letras.
Las desventajas son:
- Cuando la constante nombrada no se define cerca de su uso, daña la localidad y, por lo tanto, la comprensibilidad del código. Poner el 52 en un lugar posiblemente distante significa que, para comprender completamente el funcionamiento del bucle "for" (por ejemplo, para estimar el tiempo de ejecución del bucle), uno debe rastrear la definición y verificar que sea el número esperado . Esto es fácil de evitar (reubicando la declaración) cuando la constante solo se usa en una parte del código. Cuando la constante nombrada se usa en porciones dispares, por otro lado, la ubicación remota es una pista para el lector de que el mismo valor aparece en otros lugares del código, lo que también puede valer la pena investigar.
- Puede hacer que el código sea más detallado. La declaración de la constante agrega una línea. Cuando el nombre de la constante es más largo que el del valor, particularmente si varias de estas constantes aparecen en una línea, puede ser necesario dividir una declaración lógica del código en varias líneas. Un aumento en la verbosidad puede estar justificado cuando existe cierta probabilidad de confusión acerca de la constante, o cuando existe la probabilidad de que sea necesario cambiar la constante, como la reutilización de una rutina de barajado para otros juegos de cartas. También puede justificarse como un aumento de la expresividad.
- Puede ser más lento procesar la expresión
deckSize + 1
en tiempo de ejecución que el valor "53", aunque la mayoría de los compiladores e intérpretes modernos notarán quedeckSize
se ha declarado como una constante y precalcularán el valor 53 en el código compilado. Incluso cuando esa no sea una opción, la optimización del ciclo moverá la adición para que se realice antes del ciclo. Por lo tanto, generalmente no hay una penalización de velocidad (o es insignificante) en comparación con el uso de números mágicos en el código. - Puede dificultar la depuración en sistemas donde el depurador no muestra los valores de las constantes (por ejemplo, porque el compilador los ha optimizado).
Usos aceptados
En algunos contextos, el uso de constantes numéricas sin nombre es generalmente aceptado (y posiblemente "no es mágico"). Si bien dicha aceptación es subjetiva y, a menudo, depende de los hábitos de codificación individuales, los siguientes son ejemplos comunes:
- el uso de 0 y 1 como valores iniciales o incrementales en un bucle for , como
for (int i = 0; i < max; i += 1)
- el uso de 2 para verificar si un número es par o impar, como en
isEven = (x % 2 == 0)
, donde%
está el operador de módulo - el uso de constantes aritméticas simples, por ejemplo, en expresiones como
circumference = 2 * Math.PI * radius
, [1] o para calcular el discriminante de una ecuación cuadrática comod = b^2 − 4*a*c
- el uso de potencias de 10 para convertir valores métricos (por ejemplo, entre gramos y kilogramos) o para calcular valores porcentuales y por mil
- exponentes en expresiones como
(f(x) ** 2 + f(y) ** 2) ** 0.5
para
Las constantes de 1 y 0 se utilizan a veces para representar los booleanos valores verdadero y falso en lenguajes de programación sin un tipo booleano, tales como las versiones anteriores de C . La mayoría de los lenguajes de programación modernos proporcionan un tipo primitivoboolean
o, por lo que el uso de 0 y 1 no es aconsejable. Esto puede ser más confuso ya que 0 a veces significa éxito programático (cuando -1 significa fracaso) y fracaso en otros casos (cuando 1 significa éxito).bool
En C y C ++, a veces se usa 0 para representar el puntero nulo . Al igual que con los valores booleanos, la biblioteca estándar de C incluye una definición de macro NULL
cuyo uso se recomienda. Otros lenguajes proporcionan una específica null
o nil
valor y cuando este es el caso hay alternativa debe ser utilizado. La constante de puntero nullptr
con tipo se introdujo con C ++ 11.
Indicadores de formato
Origen
Los indicadores de formato se utilizaron por primera vez en el código fuente Unix de la versión 7 . [ cita requerida ]
Unix fue portado a uno de los primeros DEC PDP-11 /20, que no tenía protección de memoria . Entonces, las primeras versiones de Unix usaban el modelo de referencia de memoria reubicable . [5] Pre sexta edición de Unix versiones leer un archivo ejecutable en la memoria y saltó a la primera dirección de memoria de baja del programa, dirección relativa cero. Con el desarrollo de las versiones paginadas de Unix, se creó un encabezado para describir los componentes de la imagen ejecutable . Además, se insertó una instrucción de bifurcación como la primera palabra del encabezado para omitir el encabezado e iniciar el programa. De esta manera, un programa podría ejecutarse en el modo de referencia de memoria reubicable anterior (normal) o en modo paginado. A medida que se desarrollaron más formatos ejecutables, se agregaron nuevas constantes incrementando el desplazamiento de la rama . [6]
En el código fuente de la Sexta Edición del cargador de programas de Unix, la función exec () lee la imagen ejecutable ( binaria ) del sistema de archivos. Los primeros 8 bytes del archivo eran un encabezado que contenía los tamaños del programa (texto) y las áreas de datos inicializadas (globales). Además, la primera palabra de 16 bits del encabezado se comparó con dos constantes para determinar si la imagen ejecutable contenía referencias de memoria reubicables (normal), la imagen ejecutable de solo lectura paginada recién implementada o la instrucción separada y la imagen paginada de datos. [7] No se mencionó la función dual de la constante de encabezado, pero el byte de orden superior de la constante era, de hecho, el código de operación para la instrucción de bifurcación PDP-11 ( octal 000407 o hexadecimal 0107). Agregar siete al contador del programa mostró que si se ejecutaba esta constante , ramificaría el servicio exec () de Unix sobre el encabezado de ocho bytes de la imagen ejecutable e iniciaría el programa.
Dado que las ediciones sexta y séptima de Unix emplearon código de paginación, se ocultó la función dual de la constante de encabezado. Es decir, el servicio exec () lee los datos del encabezado del archivo ejecutable ( meta ) en un búfer de espacio del kernel , pero lee la imagen ejecutable en el espacio de usuario , por lo que no usa la función de ramificación de la constante. La creación de números mágicos se implementó en el enlazador y cargador de Unix y la ramificación de números mágicos probablemente todavía se usaba en el conjunto de programas de diagnóstico independientes que venían con las ediciones Sexta y Séptima. Por lo tanto, la constante del encabezado proporcionó una ilusión y cumplió con los criterios para la magia .
En la versión siete de Unix, la constante de encabezado no se probó directamente, sino que se asignó a una variable etiquetada como ux_mag [8] y, posteriormente, se la denominó número mágico . Probablemente debido a su singularidad, el término número mágico pasó a significar el tipo de formato ejecutable, luego se expandió para significar el tipo de sistema de archivos y se expandió nuevamente para significar cualquier tipo de archivo.
En archivos
Los números mágicos son comunes en los programas de muchos sistemas operativos. Los números mágicos implementan datos fuertemente tipados y son una forma de señalización dentro de banda para el programa de control que lee los tipos de datos en el tiempo de ejecución del programa. Muchos archivos tienen tales constantes que identifican los datos contenidos. La detección de estas constantes en los archivos es una forma sencilla y eficaz de distinguir entre muchos formatos de archivo y puede generar más información en tiempo de ejecución .
- Ejemplos de
- Los archivos de clase Java compilados ( código de bytes ) y los binarios Mach-O comienzan con hexadecimal
CAFEBABE
. Cuando se comprime con Pack200, los bytes se cambian aCAFED00D
. - Los archivos de imagen GIF tienen el código ASCII para "GIF89a" (
47
49
46
38
39
61
) o "GIF87a" (47
49
46
38
37
61
) - Los archivos de imagen JPEG comienzan con
FF
D8
y terminan conFF
D9
. Los archivos JPEG / JFIF contienen el código ASCII para "JFIF" (4A
46
49
46
) como una cadena terminada en nulo. Los archivos JPEG / Exif contienen el código ASCII para "Exif" (45
78
69
66
) también como una cadena terminada en nulo, seguida de más metadatos sobre el archivo. - Los archivos de imagen PNG comienzan con una firma de 8 bytes que identifica el archivo como un archivo PNG y permite la detección de problemas comunes de transferencia de archivos:
\211
P
N
G
\r
\n
\032
\n
(89
50
4E
47
0D
0A
1A
0A
). Esa firma contiene varios caracteres de nueva línea para permitir la detección de conversiones de nueva línea automatizadas injustificadas, como transferir el archivo mediante FTP con el modo de transferencia ASCII en lugar del modo binario . [9] - Standard MIDI archivos de audio tienen el ASCII código para "mthd" ( M IDI T acumular h ea d er,
4D
54
68
64
) seguido por más de metadatos. - Unix o Linux guiones pueden comenzar con un "tinglado" ( #! ,
23
21
) Seguido de la ruta a un intérprete , si el intérprete es probable que sea diferente a la de la que se invocó el guión. - Los ejecutables ELF comienzan con
7F
E
L
F
- Los archivos y programas PostScript comienzan con "%!" (
25
21
). - Los archivos PDF comienzan con "% PDF" (hexadecimal
25
50
44
46
). - Los archivos ejecutables DOS MZ y el stub EXE de los archivos Microsoft Windows PE (Portable Executable) comienzan con los caracteres "MZ" (
4D
5A
), las iniciales del diseñador del formato de archivo, Mark Zbikowski . La definición permite el poco común "ZM" (5A
4D
) también para dosZMXP, un EXE que no es PE. [10] - El formato de superbloque Berkeley Fast File System se identifica como
19
54
01
19
o01
19
54
según la versión; ambos representan el cumpleaños del autor, Marshall Kirk McKusick . - El Master Boot Record de los dispositivos de almacenamiento de arranque en casi todos los PC IBM compatibles con IA-32 tiene un código de como sus dos últimos bytes.
55
AA
- Los ejecutables para los sistemas de videojuegos portátiles Game Boy y Game Boy Advance tienen un número mágico de 48 bytes o 156 bytes, respectivamente, en un lugar fijo en el encabezado. Este número mágico codifica un mapa de bits del logotipo de Nintendo .
- Los archivos Hunk ejecutables del software Amiga que se ejecutan en las máquinas Amiga classic 68000 comenzaron con el número hexadecimal $ 000003f3, apodado "Magic Cookie".
- En Amiga, la única dirección absoluta en el sistema es hexadecimal $ 0000 0004 (ubicación de memoria 4), que contiene la ubicación de inicio llamada SysBase, un puntero a exec.library, el llamado núcleo de Amiga.
- Los archivos PEF , utilizados por los ejecutables clásicos de Mac OS y BeOS para PowerPC , contienen el código ASCII para "Joy!" (
4A
6F
79
21
) como prefijo. - TIFF archivos comienzan ya sea con
II
oMM
seguidos por 42 como un número entero de dos bytes en pequeña o grande endian orden de los bytes.II
es para Intel, que utiliza el orden de bytes little endian , por lo que el número mágico es49
49
2A
00
.MM
es para Motorola, que utiliza el orden de bytes big endian , por lo que el número mágico es4D
4D
00
2A
. - Los archivos de texto Unicode codificados en UTF-16 a menudo comienzan con la marca de orden de bytes para detectar endianness (
FE
FF
para big endian yFF
FE
little endian). Y en Microsoft Windows , los archivos de texto UTF-8 a menudo comienzan con la codificación UTF-8 del mismo carácterEF
BB
BF
,. - Los archivos LLVM Bitcode comienzan con
BC
(0x42, 0x43) - Los archivos WAD comienzan con
IWAD
oPWAD
(para Doom ),WAD2
(para Quake ) yWAD3
(para Half-Life ). - Los archivos de formato binario de archivo compuesto de Microsoft (conocido principalmente como uno de los formatos más antiguos de los documentos de Microsoft Office ) comienzan con
D0
CF
11
E0
, que es visualmente sugerente de la palabra "DOCFILE0". - Los encabezados de los archivos ZIP comienzan con "PK" (
50
4B
), las iniciales de Phil Katz , autor de la utilidad de compresión de DOS PKZIP . - Los encabezados de los archivos 7z comienzan con "7z" (número mágico completo :)
37
7A
BC
AF
27
1C
.
- Detección
El programa de utilidad Unix file
puede leer e interpretar números mágicos de archivos, y el archivo que se usa para analizar la información se llama mágico . La utilidad de Windows TrID tiene un propósito similar.
En protocolos
- Ejemplos de
- El protocolo OSCAR , utilizado en AIM / ICQ , antepone las solicitudes con
2A
. - En el protocolo RFB utilizado por VNC , un cliente inicia su conversación con un servidor enviando "RFB" (
52
46
42
por "Remote Frame Buffer") seguido del número de versión del protocolo del cliente. - En el protocolo SMB utilizado por Microsoft Windows, cada solicitud SMB o respuesta del servidor comienza con "
FF
53
4D
42
", o"\xFFSMB"
al inicio de la solicitud SMB. - En el protocolo MSRPC utilizado por Microsoft Windows, cada solicitud basada en TCP comienza con
05
el inicio de la solicitud (que representa Microsoft DCE / RPC Versión 5), seguida inmediatamente por una00
o01
para la versión menor. En las solicitudes MSRPC basadas en UDP, el primer byte es siempre04
. - En interfaces COM y DCOM calculadas , llamadas OBJREF , siempre comience con la secuencia de bytes "MEOW" (
4D
45
4F
57
). Las extensiones de depuración (utilizadas para el enlace de canales DCOM) están precedidas por la secuencia de bytes "MARB" (4D
41
52
42
). - Las solicitudes de seguimiento de BitTorrent no cifradas comienzan con un solo byte que contiene el valor que
19
representa la longitud del encabezado, seguido inmediatamente por la frase "Protocolo BitTorrent" en la posición 1 del byte. - El tráfico de eDonkey2000 / eMule comienza con un solo byte que representa la versión del cliente. Actualmente
E3
representa a un cliente de eDonkey,C5
representa a eMule yD4
representa a eMule comprimido. - Los primeros
04
bytes de un bloque en Bitcoin Blockchain contienen un número mágico que sirve como identificador de red. El valor es una constante0xD9B4BEF9
, que indica la red principal, mientras que la constante0xDAB5BFFA
indica la red de prueba. - Las transacciones SSL siempre comienzan con un mensaje de "saludo del cliente". El esquema de encapsulación de registros utilizado para prefijar todos los paquetes SSL consta de formularios de encabezado de dos y tres bytes. Por lo general, un mensaje de saludo de cliente SSL versión 2 tiene el prefijo
80
ay una respuesta del servidor SSLv3 a un saludo de cliente comienza con16
(aunque esto puede variar). - Los paquetes DHCP usan un valor de "cookie mágica" de '
0x63
0x82
0x53
0x63
' al comienzo de la sección de opciones del paquete. Este valor se incluye en todos los tipos de paquetes DHCP. - Las conexiones HTTP / 2 se abren con el prefacio '
0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a
' o "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n
". El prefacio está diseñado para evitar el procesamiento de tramas por parte de servidores e intermediarios que admiten versiones anteriores de HTTP pero no 2.0.
En interfaces
Los números mágicos son comunes en las funciones e interfaces de API en muchos sistemas operativos , incluidos DOS , Windows y NetWare :
- Ejemplos de
- Los BIOS compatibles con IBM PC utilizan valores mágicos
0000
y1234
deciden si el sistema debe contar la memoria o no al reiniciar, realizando así un arranque en frío o en caliente. Estos valores también son utilizados por los administradores de memoria EMM386 que interceptan las solicitudes de arranque. [11] Los BIOS también utilizan valores mágicos55 AA
para determinar si un disco es de arranque. [12] - El caché de disco de MS-DOS SMARTDRV (con nombre en código "Bambi") utiliza valores mágicos BABE y EBAB en funciones API. [11]
- Muchos controladores DR DOS , Novell DOS y OpenDOS desarrollados en el antiguo Centro Europeo de Desarrollo en el Reino Unido utilizan el valor 0EDC como símbolo mágico al invocar o proporcionar funcionalidad adicional además de las funciones estándar de DOS (emuladas), siendo NWCACHE un ejemplo. [11]
Otros usos
- Ejemplos de
- La dirección MAC predeterminada en los SOC de Texas Instruments es DE: AD: BE: EF: 00: 00. [13]
Límites de tipo de datos
Esta es una lista de límites de tipos de almacenamiento de datos: [14]
Decimal | Maleficio | Descripción |
---|---|---|
18,446,744,073,709,551,615 | FFFF FFFF FFFF FFFF | El valor máximo de 64 bits sin signo (2 64 - 1) |
9.223.372.036.854.775.807 | 7FFF FFFF FFFF FFFF | El valor máximo de 64 bits con signo (2 63 - 1) |
4.294.967.295 | FFFF FFFF | El valor máximo de 32 bits sin signo (2 32 - 1) |
2,147,483,647 | 7FFF FFFF | El valor máximo de 32 bits con signo (2 31 - 1) |
65.535 | FFFF | El valor máximo de 16 bits sin signo (2 16 - 1) |
32,767 | 7FFF | El valor máximo de 16 bits con signo (2 15 - 1) |
255 | FF | El valor máximo de 8 bits sin signo (2 8 - 1) |
127 | 7F | El valor máximo de 8 bits con signo (2 7 - 1) |
−128 | 80 | Valor mínimo de 8 bits con signo |
−32,768 | 8000 | Valor mínimo de 16 bits con signo |
−2,147,483,648 | 8000 0000 | Valor mínimo de 32 bits con signo |
−9,223,372,036,854,775,808 | 8000 0000 0000 0000 | Valor mínimo de 64 bits con signo |
GUID
Es posible crear o alterar identificadores únicos globales (GUID) para que sean memorables, pero esto se desaconseja ya que compromete su fuerza como identificadores casi únicos. [15] [16] Las especificaciones para generar GUID y UUID son bastante complejas, que es lo que los lleva a ser virtualmente únicos, si se implementan correctamente. Solo deben ser generados por una herramienta de software acreditada. [ cita requerida ]
Los números de ID de producto de Microsoft Windows para productos de Microsoft Office a veces terminan con 0000-0000-0000000FF1CE ("OFFICE"), como { 90160000-008C-0000-0000-0000000FF1CE }, el ID de producto para " Hacer clic y ejecutar de Office 16 Componente de extensibilidad ".
Java usa varios GUID que comienzan con CAFEEFAC
. [17]
En la tabla de particiones GUID del esquema de particiones GPT, las particiones de arranque del BIOS utilizan el GUID especial { 21686148-6449-6E6F-744E-656564454649 } [18] que no sigue la definición de GUID; en cambio, se forma usando los códigos ASCII para la cadena " Hah! IdontNeedEFI " parcialmente en orden little endian . [19]
Valores de depuración
Los valores de depuración mágica son valores específicos que se escriben en la memoria durante la asignación o desasignación, de modo que luego será posible saber si se han corrompido o no, y hacer que sea obvio cuando se están utilizando valores tomados de la memoria no inicializada. La memoria generalmente se ve en hexadecimal, por lo que los valores repetidos o hexadecimales memorables son comunes. Se pueden preferir valores numéricamente impares para que los procesadores sin direccionamiento de bytes fallarán al intentar usarlos como punteros (que deben caer en direcciones pares). Se deben elegir valores que estén alejados de las direcciones probables (el código del programa, los datos estáticos, los datos del montón o la pila). De manera similar, pueden elegirse de manera que no sean códigos válidos en el conjunto de instrucciones para la arquitectura dada.
Dado que es muy poco probable, aunque posible, que un entero de 32 bits tome este valor específico, la aparición de tal número en un depurador o volcado de memoria probablemente indique un error como un desbordamiento del búfer o una variable no inicializada .
Los ejemplos famosos y comunes incluyen:
Código | Descripción |
---|---|
00008123 | Utilizado en MS Visual C ++. Los punteros eliminados se establecen en este valor, por lo que lanzan una excepción, cuando se usan después; es un alias más reconocible para la dirección cero. Se activa con la opción Security Development Lifecycle (/ sdl). [20] |
..FACADE | "Fachada" , utilizado por varios RTOS |
1BADB002 | "1 arranque incorrecto" , número mágico del encabezado de arranque múltiple [21] |
8BADF00D | "Ate bad food" , indica que una aplicación de Apple iOS ha finalizado debido a que se agotó el tiempo de espera del perro guardián. [22] |
A5A5A5A5 | Se utiliza en el desarrollo integrado porque el patrón de bits alternos (1010 0101) crea un patrón fácilmente reconocible en osciloscopios y analizadores lógicos . |
A5 | Se usa en PHK malloc (3) de FreeBSD para depurar cuando /etc/malloc.conf está enlazado simbólicamente a "-J" para inicializar toda la memoria recién asignada ya que este valor no es un puntero NULL o un carácter ASCII NUL. |
ABABABAB | Usado por el depurador HeapAlloc () de Microsoft para marcar los bytes de protección de "tierra de nadie" después de la memoria del montón asignada. [23] |
ABADBABE | "Un bebé malo" , utilizado por Apple como el número mágico "Boot Zero Block" |
ABBABABE | " ABBA babe" , utilizado por el montón de memoria Driver Parallel Lines . |
ABADCAFE | "Un mal café" , se utiliza para inicializar toda la memoria no asignada (Mungwall, AmigaOS ) |
B16B00B5 | "Pechos Grandes" , anteriormente requerido por Microsoft 's Hyper-V hipervisor para ser utilizado por los clientes de Linux como la mitad superior de su 'Identificación del invitado' [24] |
BAADF00D | "Mala comida" , utilizado por el depurador HeapAlloc () de Microsoft para marcar la memoria de montón asignada no inicializada [23] |
BAAAAAAD | "Baaaaaad" , indica que el registro de Apple iOS es una muestra de todo el sistema, no un informe de fallos [22] |
BAD22222 | "Malo con demasiada frecuencia" , indica que una aplicación de VoIP de Apple iOS se ha cancelado porque se reanuda con demasiada frecuencia [22] |
BADBADBADBAD | "Malo malo malo malo" , memoria "no inicializada" de grandes sistemas de Burroughs (palabras de 48 bits) |
BADC0FFEE0DDF00D | "Mala comida extraña de café" , utilizado en sistemas IBM RS / 6000 de 64 bits para indicar registros de CPU no inicializados |
BADDCAFE | "Bad café" , por Sun Microsystems ' Solaris , marcas sin inicializar la memoria del núcleo (KMEM_UNINITIALIZED_PATTERN) |
BBADBEEF | "Bad beef" , utilizado en WebKit [ aclaración necesaria ] |
BEEFCACE | "Pastel de carne" , utilizado por Microsoft .NET como un número mágico en los archivos de recursos |
C00010FF | "Refrescarse" , indica que el sistema operativo eliminó la aplicación Apple iOS en respuesta a un evento térmico [22] |
CAFEBABE | "Cafe babe" , utilizado por Java para archivos de clase |
CAFED00D | "Cafe dude" , utilizado por Java para su compresión pack200 |
CAFEFEED | "Café alimentar" , usado por Sun Microsystems ' Solaris depuración del núcleo de kmemfree marca () Memoria |
CCCCCCCC | Utilizado por la biblioteca de tiempo de ejecución de depuración C ++ de Microsoft y muchos entornos DOS para marcar la memoria de pila no inicializada . CC se parece al código de operación de la interrupción del punto de interrupción de depuración INT 3 en los procesadores x86. |
CDCDCDCD | Utilizado por la función de depuración malloc () de C / C ++ de Microsoft para marcar la memoria del montón no inicializada, generalmente devuelta desde HeapAlloc () [23] |
0D15EA5E | "Enfermedad de cero" , utilizado como una bandera para indicar el arranque regular en las Nintendo GameCube y Wii consolas |
DDDDDDDD | Utilizado por SmartHeap de MicroQuill y la función debug free () de C / C ++ de Microsoft para marcar la memoria del montón liberada [23] |
DEAD10CC | "Dead lock" , indica que una aplicación de Apple iOS ha finalizado porque retuvo un recurso del sistema mientras se ejecutaba en segundo plano [22] |
DEADBABE | "Dead babe" , utilizado al comienzo de los archivos de arena IRIX de Silicon Graphics |
DEADBEEF | "Dead beef" , famoso en sistemas IBM como el RS / 6000 , también se utiliza en los sistemas operativos clásicos de Mac OS , OPENSTEP Enterprise y Commodore Amiga . En Sun Microsystems ' Solaris , marcas liberados memoria del núcleo (KMEM_FREE_PATTERN) |
DEADCAFE | "Dead cafe" , utilizado por Microsoft .NET como número de error en archivos DLL |
DEADC0DE | "Código muerto" , utilizado como marcador en el firmware OpenWRT para indicar el comienzo del sistema de archivos jffs2 que se creará al final del firmware estático |
DEADFA11 | "Fallo muerto" , indica que el usuario ha forzado el cierre de una aplicación de Apple iOS [22] |
DEADF00D | "Comida muerta" , utilizada por Mungwall en el Commodore Amiga para marcar la memoria asignada pero no inicializada [25] |
DEFEC8ED | "Defecated" , utilizado para volcados de núcleo de OpenSolaris |
DEADDEAD | "Dead Dead" indica que el usuario inició deliberadamente un volcado por caída desde el depurador del kernel o desde el teclado. [26] |
D00D2BAD | "Dude, Too Bad", utilizado por Safari, se bloquea en macOS Big Sur. [27] |
EBEBEBEB | De SmartHeap de MicroQuill |
FADEDEAD | "Fade dead" , viene al final para identificar cada script de AppleScript |
FDFDFDFD | Utilizado por la función de depuración malloc () de C / C ++ de Microsoft para marcar los bytes de protección de "tierra de nadie" antes y después de la memoria dinámica asignada, [23] y algunas funciones de depuración Secure C-Runtime implementadas por Microsoft (p . |
FEE1DEAD | "Feel dead" , utilizado por Linux reboot () syscall |
FEEDFACE | "Feed face" , visto en los binarios de PowerPC Mach-O en la plataforma macOS de Apple Inc. En Sun Microsystems ' Solaris , las marcas de la zona roja (KMEM_REDZONE_PATTERN) Utilizado por el reproductor VLC y algunas cámaras IP en el protocolo RTP / RTCP , el reproductor VLC envía cuatro bytes en el orden del endianness del sistema. Algunas cámaras IP esperan que el jugador envíe este número mágico y no inicien la transmisión si no se recibe. |
FEEEFEEE | "Fee fee" , utilizado por la depuración HeapFree () de Microsoft para marcar la memoria del montón liberada. Algunos valores contables internos cercanos también pueden tener la palabra alta establecida en FEEE. [23] |
La mayoría de estos tienen 32 bits de longitud, el tamaño de palabra de la mayoría de las computadoras con arquitectura de 32 bits.
La prevalencia de estos valores en la tecnología de Microsoft no es una coincidencia; se tratan en detalle en el libro de Steve Maguire Writing Solid Code de Microsoft Press . Él da una variedad de criterios para estos valores, tales como:
- No deberían ser útiles; es decir, se debe esperar que la mayoría de los algoritmos que operan en ellos hagan algo inusual. Números como cero no se ajustan a este criterio.
- El programador debería reconocerlos fácilmente como valores no válidos en el depurador.
- En las máquinas que no tienen alineación de bytes , deben ser números impares , de modo que desreferenciarlos como direcciones cause una excepción.
- Deberían provocar una excepción, o incluso una interrupción del depurador, si se ejecutan como código.
Dado que a menudo se usaban para marcar áreas de la memoria que estaban esencialmente vacías, algunos de estos términos llegaron a usarse en frases que significan "desaparecido, abortado, borrado de la memoria"; por ejemplo, "Su programa es DEADBEEF" [ cita requerida ] .
Ver también
- Hilo mágico
- Formato de archivo § Número mágico
- Lista de firmas de archivos
- FourCC
- Código difícil
- Magia (programación)
- NaN (no es un número)
- Tipo enumerado
- Hexspeak , para otro conjunto de valores mágicos
- Nada bajo mi número de la manga sobre constantes mágicas en algoritmos criptográficos
- Errores de formato y almacenamiento de tiempo , para problemas que pueden ser causados por magia
- Valor centinela (también conocido como valor de bandera, valor de viaje, valor de pícaro, valor de señal, datos ficticios)
- Valor canario , valor especial para detectar desbordamientos de búfer
- XYZZY (palabra mágica)
- Raíz cuadrada inversa rápida , usando la constante 0x5F3759DF
Referencias
- ↑ a b c Martin, Robert C. (2009). "Capítulo 17: olores y heurística - G25 reemplazar números mágicos con constantes con nombre". Código limpio: un manual de artesanía de software ágil . Boston: Prentice Hall. pag. 300 . ISBN 978-0-13-235088-4.
- ^ Martin, Robert C. (2009). "Capítulo 17: olores y heurística - Intención oscurecida G16". Código limpio: un manual de artesanía de software ágil . Boston: Prentice Hall. pag. 295 . ISBN 978-0-13-235088-4.
- ^ Maguire, James (9 de diciembre de 2008). "Bjarne Stroustrup sobre la educación de desarrolladores de software" . Datamation.com . Archivado desde el original el 23 de junio de 2018.
- ^ Vogel, Jeff (29 de mayo de 2007). "Seis formas de escribir código más comprensible" . Desarrollador de IBM .
- ^ "Comentarios raros y hechos extraños en Unix" . Bell Labs . 2002-06-22. Archivado desde el original el 4 de noviembre de 2006.
- ^ Comunicación personal con Dennis M. Ritchie.
- ^ "El árbol de Unix V6 / usr / sys / ken / sys1.c" . La Sociedad de Herencia de Unix . Archivado desde el original el 20 de octubre de 2008.
- ^ "El árbol de Unix V7 / usr / sys / sys / sys1.c" . La Sociedad de Herencia de Unix . Archivado desde el original el 20 de octubre de 2008.
- ^ "PNG (Portable Network Graphics) Especificación Versión 1.0: 12.11. Firma de archivo PNG" . MIT . 1996-10-01.
- ^ Chen, Raymond (24 de marzo de 2008). "¿Cuál es la diferencia entre las extensiones COM y EXE?" . Lo viejo y nuevo . Archivado desde el original el 18 de febrero de 2019.
- ^ a b c Paul, Matthias R. (3 de abril de 2002). "[fd-dev] Ctrl + Alt + Supr" . Freedos-dev . Archivado desde el original el 9 de septiembre de 2017 . Consultado el 9 de septiembre de 2017 .(NB. Menciona una serie de valores mágicos utilizados por BIOS compatibles con IBM PC (0000h, 1234h), administradores de memoria DOS como EMM386 (1234h) y cachés de disco como SMARTDRV (EBABh, BABEh) y NWCACHE (0EDCh, EBABh, 6756h). )
- ^ "El proceso de arranque BIOS / MBR" . Base de conocimientos de NeoSmart . 2015-01-25 . Consultado el 3 de febrero de 2019 .
- ^ "Comunidad TI E2E: ¿Alguien sabe si se pueden realizar las siguientes configuraciones con la herramienta MCP CLI?" . Texas Instruments . 2011-08-27.
- ^ Poley, Josh (30 de septiembre de 2009). "Números mágicos: enteros" . MSDN .
- ^ Recién llegado, Joseph M. (13 de octubre de 2001). "Gestión de mensajes: garantía de unicidad" . Desarrollador Fusion . Consultado el 16 de noviembre de 2007 .
- ^ Osterman, Larry (21 de julio de 2005). "Los UUID sólo son únicos si los genera ..." WebLog de Larry Osterman: Confessions of an Old Fogy . MSDN . Consultado el 16 de noviembre de 2007 .
- ^ "Especificación de versiones de JRE de la familia para subprogramas de Java" . Oracle . Consultado el 18 de junio de 2010 .
- ^ "Instalación de GNU GRUB, Sección 3.4: Instalación de BIOS" . Gnu.org . Consultado el 26 de junio de 2014 .
- ^ Heddings, Lowell (3 de noviembre de 2014). "Números mágicos: los códigos secretos que los programadores esconden en tu PC" . How-To Geek . Consultado el 3 de octubre de 2017 .
- ^ Cavit, Doug (24 de abril de 2012). "Protección contra la reutilización de referencias de objetos obsoletos" . Microsoft Secure . Consultado el 26 de julio de 2018 .
- ^ Boleyn, Erich Stefan (4 de abril de 1995). "Comentarios sobre la propuesta" MultiBoot Standard " . Uruk.org .
- ^ a b c d e f "Nota técnica TN2151: comprensión y análisis de informes de bloqueo de aplicaciones" . Documentación para desarrolladores de Apple . 2009-01-29.
- ^ a b c d e f Birkett, Andrew. "Internos del montón de CRT de depuración de Win32" . Nobugs.org .
- ^ McNamara, Paul (19 de julio de 2012). "El código de Microsoft contiene la frase 'pechos grandes' ... Sí, de verdad" . Mundo de la red .
- ^ Scheppner, Carolyn. "Guía Amiga Mail Vol.2" . Cataclysm.cx . Archivado desde el original el 18 de julio de 2011 . Consultado el 20 de agosto de 2010 .
- ^ "Verificación de errores 0xDEADDEAD MANUALLY_INITIATED_CRASH1" . Documentación de Microsoft .
- ^ "Safari versión 14.0.1 se cierra inesperadamente" .
- ^ "strncat_s, _strncat_s_l, wcsncat_s, _wcsncat_s_l, _mbsncat_s, _mbsncat_s_l" . Documentación de Microsoft . Consultado el 16 de enero de 2019 .