Número mágico (programação).
Valor numérico com significado pouco claro
Em programação de computadores, um número mágico ou assinatura de arquivo é um literal numérico no código-fonte que possui um significado especial e específico que não é totalmente claro para o leitor. Também em computação, mas não restrito à programação, o termo é usado para um número que identifica um conceito específico, mas cujo significado não é totalmente claro sem conhecimento adicional. Por exemplo, alguns formatos de arquivo são identificados por um número mágico embutido no arquivo ). Além disso, um número que está associado de forma relativamente única a um conceito específico, como um identificador único universal, pode ser classificado como número mágico.
Literal numérico
Um número mágico ou constante mágica é um literal numérico no código-fonte que possui um significado especial e pouco claro no contexto. Isso é considerado um antipadrão e quebra uma das regras mais antigas da programação, que remonta aos manuais de COBOL, FORTRAN e PL/1 da década de 1960.
Por exemplo, no código a seguir, que calcula um preço após impostos, 1.05 é um número mágico, já que o valor codifica a alíquota do imposto sobre vendas, 5%, de uma forma pouco óbvia.
price_after_tax = 1.05 * price
O uso de números mágicos no código obscurece a intenção dos desenvolvedores ao escolher aquele número, aumenta as chances de erros sutis e torna mais difícil adaptar e estender o programa no futuro. Como exemplo, é difícil saber se cada dígito em 3.14159265358979323846 foi digitado corretamente, ou se essa constante de pi pode ser truncada para 3.14159 sem afetar a funcionalidade do programa com sua precisão reduzida. Substituir todos os números mágicos significativos por constantes nomeadas (também chamadas de variáveis explicativas) torna os programas mais fáceis de ler, entender e manter.
O exemplo acima pode ser melhorado adicionando uma variável com nome descritivo:
TAX = 0.05 price_after_tax = (1.0 + TAX) * price
Um bom nome pode resultar em código mais facilmente compreendido por um mantenedor que não seja o autor original, e até pelo próprio autor original depois de algum tempo. Um exemplo de constante com nome pouco informativo é int SIXTEEN = 16, enquanto int NUMBER_OF_BITS = 16 pode ser mais útil.
Dados não numéricos podem ter as mesmas propriedades mágicas e, portanto, os mesmos problemas dos números mágicos. Assim, declarar const string testUserName = "John" e usar testUserName pode ser melhor do que usar o literal "John" diretamente.
Exemplo
Por exemplo, se for necessário embaralhar aleatoriamente os valores em um vetor que representa um baralho padrão de cartas de baralho, este pseudocódigo realiza a tarefa usando o algoritmo de embaralhamento Fisher–Yates:
for i from 1 to 52
j := i + randomInt(53 - i) - 1
a.swapEntries(i, j)
onde a é um objeto vetor, a função randomInt(x) escolhe um inteiro aleatório entre 1 e x, inclusive, e swapEntries(i, j) troca a i-ésima e a j-ésima entradas do vetor. No exemplo anterior, 52 e 53 são números mágicos, e além disso não têm relação clara entre si. É considerado melhor estilo de programação escrever o seguinte:
int deckSize:= 52
for i from 1 to deckSize
j := i + randomInt(deckSize + 1 - i) - 1
a.swapEntries(i, j)
Isso é preferível por vários motivos:
- Melhor legibilidade. Um programador que lê o primeiro exemplo pode se perguntar: O que o número 52 significa aqui? Por que 52? O programador talvez consiga inferir o significado após ler o código com atenção, mas isso não é óbvio. Os números mágicos tornam-se particularmente confusos quando o mesmo número é usado para finalidades diferentes em uma mesma seção do código.
- Mais fácil de manter. É mais fácil alterar o valor do número, pois ele não está duplicado. Mudar o valor de um número mágico é propenso a erros, porque o mesmo valor costuma ser usado várias vezes em diferentes lugares do programa. Além disso, quando duas variáveis ou números semanticamente distintos têm o mesmo valor, eles podem ser acidentalmente editados juntos. Para modificar o primeiro exemplo de modo a embaralhar um baralho de Tarô, que tem 78 cartas, um programador poderia ingenuamente substituir cada ocorrência de 52 no programa por 78. Isso causaria dois problemas. Primeiro, deixaria passar o valor 53 na segunda linha do exemplo, o que faria o algoritmo falhar de forma sutil. Segundo, provavelmente substituiria os caracteres "52" em todos os lugares, independentemente de se referirem ao tamanho do baralho ou a algo completamente diferente, como o número de semanas em um ano do calendário gregoriano, ou, de forma mais traiçoeira, fazerem parte de um número como "1523", o que tudo introduziria bugs. Em contraste, mudar o valor da variável
deckSizeno segundo exemplo seria uma alteração simples, de uma única linha. - Incentiva a documentação. O único lugar onde a variável nomeada é declarada é um bom lugar para documentar o que o valor significa e por que ele tem esse valor. Ter o mesmo valor em uma infinidade de lugares ou leva a comentários duplicados (e aos problemas decorrentes de atualizar alguns e esquecer outros) ou não deixa nenhum único lugar onde seja ao mesmo tempo natural para o autor explicar o valor e provável que o leitor procure por uma explicação.
- Agrupa informações. As declarações das variáveis de "números mágicos" podem ser colocadas juntas, geralmente no início de uma função ou arquivo, facilitando sua revisão e alteração.
- Detecta erros de digitação. Usar uma variável (em vez de um literal) aproveita a verificação do compilador. Digitar acidentalmente "62" em vez de "52" passaria despercebido, ao passo que digitar "
dekSize" em vez de "deckSize" faria o compilador avisar quedekSizenão foi declarada. - Reduz a digitação. Se uma IDE oferecer suporte a autocompletar código, ela preencherá a maior parte do nome da variável a partir das primeiras letras.
- Facilita a parametrização. Por exemplo, para generalizar o exemplo acima em um procedimento que embaralha um baralho com qualquer número de cartas, bastaria transformar
deckSizeem um parâmetro desse procedimento, ao passo que o primeiro exemplo exigiria várias alterações.
function shuffle (int deckSize)
for i from 1 to deckSize
j := i + randomInt(deckSize + 1 - i) - 1
a.swapEntries(i, j)
As desvantagens são:
- Quebra a localidade. Quando a constante nomeada não é definida perto de seu uso, isso prejudica a localidade e, portanto, a compreensibilidade do código. Colocar o 52 em um lugar possivelmente distante significa que, para entender completamente o funcionamento do laço "for" (por exemplo, para estimar o tempo de execução do laço), é preciso localizar a definição e verificar se é o número esperado. Isso é fácil de evitar (realocando a declaração) quando a constante é usada em apenas uma parte do código. Por outro lado, quando a constante nomeada é usada em partes distintas, a localização remota é uma pista para o leitor de que o mesmo valor aparece em outros lugares do código, que também podem valer a pena ser investigados.
- Causa verbosidade. A declaração da constante acrescenta uma linha. Quando o nome da constante é mais longo do que o valor, em especial se várias dessas constantes aparecem em uma linha, pode ser necessário dividir uma única instrução lógica do código em várias linhas. Um aumento de verbosidade pode se justificar quando há alguma probabilidade de confusão sobre a constante, ou quando há probabilidade de a constante precisar ser alterada, como o reaproveitamento de uma rotina de embaralhamento para outros jogos de cartas. Pode igualmente se justificar como um aumento de expressividade.
- Considerações de desempenho. Processar a expressão
deckSize + 1em tempo de execução pode ser mais lento do que o valor "53". Dito isso, a maioria dos compiladores modernos usa técnicas como dobra de constantes e otimização de laços para resolver a adição durante a compilação, de modo que normalmente não há penalidade de velocidade, ou ela é desprezível, em comparação ao uso de números mágicos no código. Sobretudo o custo de depuração e o tempo necessário para tentar entender um código não explicativo devem ser pesados contra o ínfimo custo de cálculo.
Uso aceito
Quando um literal numérico carece de significado especial, seu uso não é classificado como mágico, embora o que constitui "especial" seja subjetivo. Exemplos de literais que com frequência não são considerados mágicos incluem:
- Uso de 0 e 1 como valores iniciais ou de incremento em um laço for, como em
for (int i = 0; i < max; i += 1)
- Uso do 2 para verificar se um número é par ou ímpar, como em
isEven = (x % 2 == 0), onde%é o operador módulo
- Uso de literais simples, p. ex., em expressões como
circumference = 2 * Math.PI * radius, ou para calcular o discriminante de uma equação quadrática comod = b^2 − 4*a*c
- Uso de potências de 10 para converter valores métricos (p. ex. entre gramas e quilogramas) ou para calcular valores de porcentagem e por mil
- Expoentes em expressões como
(f(x) ** 2 + f(y) ** 2) ** 0.5para
- Os literais 1 e 0 são às vezes usados para representar os valores booleanos verdadeiro e falso. É discutível, mas atribuir esses valores a nomes como TRUE e FALSE pode ser melhor.
- Em C e C++, o 0 é frequentemente usado para significar ponteiro nulo, embora a biblioteca padrão de C defina uma macro
NULLe o C++ moderno inclua a palavra-chavenullptr.
Indicador de formato
Origem
Os indicadores de formato foram usados pela primeira vez no código-fonte do início do Version 7 Unix.
O Unix foi portado para um dos primeiros DEC PDP-11/20, que não tinha proteção de memória. Por isso, as primeiras versões do Unix usavam o modelo de referência de memória realocável. As versões anteriores à Sixth Edition Unix liam um arquivo executável para a memória e saltavam para o primeiro endereço de memória baixa do programa, o endereço relativo zero. Com o desenvolvimento das versões paginadas do Unix, foi criado um cabeçalho para descrever os componentes da imagem executável. Além disso, uma instrução de desvio foi inserida como a primeira palavra do cabeçalho para pular o cabeçalho e iniciar o programa. Dessa forma, um programa podia ser executado no modo (regular) mais antigo de referência de memória realocável ou no modo paginado. À medida que mais formatos de executável foram desenvolvidos, novas constantes foram adicionadas incrementando o deslocamento do desvio.
No código-fonte da Sixth Edition do carregador de programas do Unix, a função exec() lia a imagem executável (binária) do sistema de arquivos. Os primeiros 8 bytes do arquivo eram um cabeçalho contendo os tamanhos das áreas de dados do programa (texto) e inicializados (globais). Além disso, a primeira palavra de 16 bits do cabeçalho era comparada a duas constantes para determinar se a imagem executável continha referências de memória realocáveis (normal), a imagem executável paginada somente leitura recém-implementada, ou a imagem paginada com instrução e dados separados. Não havia menção ao papel duplo da constante do cabeçalho, mas o byte de ordem mais alta da constante era, na verdade, o código de operação da instrução de desvio do PDP-11 (octal 000407 ou hexadecimal 0107). Somar sete ao contador de programa mostrava que, se essa constante fosse executada, ela desviaria o serviço exec() do Unix por cima do cabeçalho de oito bytes da imagem executável e iniciaria o programa.
Como a Sixth e a Seventh Edition do Unix empregavam código de paginação, o papel duplo da constante do cabeçalho ficava oculto. Ou seja, o serviço exec() lia os dados (meta) do cabeçalho do arquivo executável para um buffer no espaço do kernel, mas lia a imagem executável para o espaço do usuário, não utilizando assim o recurso de desvio da constante. A criação de números mágicos foi implementada no ligador (linker) e no carregador (loader) do Unix, e o desvio por número mágico provavelmente ainda era usado no conjunto de programas de diagnóstico autônomos que acompanhavam a Sixth e a Seventh Edition. Assim, a constante do cabeçalho de fato proporcionava uma ilusão e atendia aos critérios de magia.
No Version Seven Unix, a constante do cabeçalho não era testada diretamente, mas atribuída a uma variável rotulada ux_mag e, posteriormente, referida como o número mágico. Provavelmente por causa de sua unicidade, o termo número mágico passou a significar o tipo de formato de executável, depois se expandiu para significar o tipo de sistema de arquivos e expandiu-se novamente para significar qualquer tipo de arquivo.
Em arquivos
Os números mágicos são comuns em programas de muitos sistemas operacionais. Os números mágicos implementam dados fortemente tipados e são uma forma de sinalização em banda para o programa controlador que lê o(s) tipo(s) de dado em tempo de execução do programa. Muitos arquivos têm constantes desse tipo que identificam os dados contidos. Detectar essas constantes em arquivos é uma maneira simples e eficaz de distinguir entre muitos formatos de arquivo e pode fornecer informações adicionais em tempo de execução.
- Exemplos
- Arquivos de classe Java compilados (bytecode) e binários Mach-O começam com o hexadecimal
CA FE BA BE. Quando comprimidos com Pack200, os bytes são alterados paraCA FE D0 0D. - Os arquivos de imagem GIF têm o código ASCII de "GIF89a" (
47 49 46 38 39 61) ou "GIF87a" (47 49 46 38 37 61) - Os arquivos de imagem JPEG começam com
FF D8e terminam comFF D9. Os arquivos JPEG/JFIF contêm a string terminada em nulo "JFIF" (4A 46 49 46 00). Os arquivos JPEG/Exif contêm a string terminada em nulo "Exif" (45 78 69 66 00), seguida de mais metadados sobre o arquivo. - Os arquivos de imagem PNG começam com uma assinatura de 8 bytes que identifica o arquivo como um arquivo PNG e permite detectar problemas comuns de transferência de arquivos: "\211PNG\r\n\032\n" (
89 50 4E 47 0D 0A 1A 0A). Essa assinatura contém vários caracteres de nova linha para permitir a detecção de conversões automáticas indevidas de quebras de linha, como a transferência do arquivo via FTP com o modo de transferência ASCII em vez do modo binário. - Os arquivos de áudio MIDI padrão têm o código ASCII de "MThd" (MIDI Track header,
4D 54 68 64) seguido de mais metadados. - Os scripts Unix ou Linux podem começar com um shebang ("#!",
23 21) seguido do caminho para um interpretador, caso o interpretador provavelmente seja diferente daquele a partir do qual o script foi invocado. - Os executáveis ELF começam com o byte
7Fseguido de "ELF" (7F 45 4C 46). - Os arquivos e programas PostScript começam com "%!" (
25 21). - Os arquivos PDF começam com "%PDF" (hexadecimal
25 50 44 46). - Os arquivos executáveis DOS MZ e o stub EXE dos arquivos PE (Portable Executable) do Microsoft Windows começam com os caracteres "MZ" (
4D 5A), as iniciais do projetista do formato de arquivo, Mark Zbikowski. A definição também permite o incomum "ZM" (5A 4D) para o dosZMXP, um EXE que não é PE. - O formato de superbloco do Berkeley Fast File System é identificado como
19 54 01 19ou01 19 54, dependendo da versão; ambos representam a data de nascimento do autor, Marshall Kirk McKusick. - O Master Boot Record de dispositivos de armazenamento inicializáveis em quase todos os compatíveis com IBM PC IA-32 tem o código
55 AAcomo seus dois últimos bytes. - Os executáveis para os videogames portáteis Game Boy e Game Boy Advance têm um número mágico de 48 bytes ou 156 bytes, respectivamente, em um ponto fixo do cabeçalho. Esse número mágico codifica um bitmap do logotipo da Nintendo.
- Os arquivos executáveis Hunk de software do Amiga, executados em máquinas Amiga clássicas com 68000, começavam todos com o número hexadecimal $000003f3, apelidado de "Magic Cookie".
- No Amiga, o único endereço absoluto do sistema é o hexadecimal $0000 0004 (posição de memória 4), que contém a posição inicial chamada SysBase, um ponteiro para a exec.library, o chamado kernel do Amiga.
- Os arquivos PEF, usados pelo Mac OS clássico e pelo BeOS para executáveis PowerPC, contêm o código ASCII de "Joy!" (
4A 6F 79 21) como prefixo. - Os arquivos TIFF começam com "II" ou "MM" seguido de 42 como um inteiro de dois bytes na ordenação de bytes little ou big endian. "II" é de Intel, que usa a ordenação de bytes little endian, então o número mágico é
49 49 2A 00. "MM" é de Motorola, que usa a ordenação de bytes big endian, então o número mágico é4D 4D 00 2A. - Os arquivos de texto Unicode codificados em UTF-16 frequentemente começam com a Byte Order Mark para detectar a endianness (
FE FFpara big endian eFF FEpara little endian). E no Microsoft Windows, os arquivos de texto UTF-8 frequentemente começam com a codificação UTF-8 do mesmo caractere,EF BB BF. - Os arquivos Bitcode LLVM começam com "BC" (
42 43). - Os arquivos WAD começam com "IWAD" ou "PWAD" (para Doom), "WAD2" (para Quake) e "WAD3" (para Half-Life).
- Os arquivos do Compound File Binary Format da Microsoft (mais conhecido como um dos formatos mais antigos de documentos do Microsoft Office) começam com
D0 CF 11 E0, que visualmente sugere a palavra "DOCFILE0". - Os cabeçalhos em arquivos ZIP frequentemente aparecem em editores de texto como "PK♥♦" (
50 4B 03 04), onde "PK" são as iniciais de Phil Katz, autor do utilitário de compressão PKZIP do DOS. - Os cabeçalhos em arquivos 7z começam com "7z" (número mágico completo:
37 7A BC AF 27 1C).
- Detecção
O programa utilitário file do Unix pode ler e interpretar números mágicos de arquivos, e o arquivo usado para analisar a informação é chamado de magic. O utilitário TrID do Windows tem propósito semelhante.
Em protocolos
- Exemplos
- O protocolo OSCAR, usado no AIM/ICQ, prefixa as requisições com
2A. - No protocolo RFB usado pelo VNC, um cliente inicia sua conversa com um servidor enviando "RFB" (
52 46 42, de "Remote Frame Buffer") seguido do número da versão do protocolo do cliente. - No protocolo SMB usado pelo Microsoft Windows, cada requisição SMB ou resposta do servidor começa com
FF 53 4D 42, ou\xFFSMBno início da requisição SMB. - No protocolo MSRPC usado pelo Microsoft Windows, cada requisição baseada em TCP começa com
05no início da requisição (representando o Microsoft DCE/RPC Versão 5), seguido imediatamente por um00ou01para a versão secundária. Nas requisições MSRPC baseadas em UDP, o primeiro byte é sempre04. - Nas interfaces empacotadas (marshalled) COM e DCOM, chamadas de OBJREFs, sempre começam com a sequência de bytes "MEOW" (
4D 45 4F 57). As extensões de depuração (usadas para o hooking de canais DCOM) são precedidas pela sequência de bytes "MARB" (4D 41 52 42). - As requisições não criptografadas de tracker BitTorrent começam com um único byte contendo o valor
19, que representa o comprimento do cabeçalho, seguido imediatamente pela frase "BitTorrent protocol" na posição de byte 1. - O tráfego eDonkey2000/eMule começa com um único byte representando a versão do cliente. Atualmente,
E3representa um cliente eDonkey,C5representa o eMule eD4representa o eMule comprimido. - Os primeiros 4 bytes de um bloco na blockchain do Bitcoin contêm um número mágico que serve como identificador da rede. O valor é
D9 B4 BE F9, que indica a rede principal, enquantoDA B5 BF FAindica a testnet. - As transações SSL sempre começam com uma mensagem "client hello". O esquema de encapsulamento de registros usado para prefixar todos os pacotes SSL consiste em formas de cabeçalho de dois e três bytes. Normalmente, uma mensagem client hello do SSL versão 2 é prefixada com um
80, e uma resposta de servidor SSLv3 a um client hello começa com16(embora isso possa variar). - Os pacotes DHCP usam um valor de "magic cookie" de
63 82 53 63no início da seção de opções do pacote. Esse valor é incluído em todos os tipos de pacote DHCP. - As conexões HTTP/2 começam com a string de 24 caracteres
PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n. Ela foi projetada para evitar o processamento de quadros por servidores e intermediários que suportam versões anteriores do HTTP, mas não a 2.0. - O handshake de abertura do WebSocket usa uma string contendo o UUIDv4
258EAFA5-E914-47DA-95CA-C5AB0DC85B11.
Em interfaces
Os números mágicos são comuns em funções de API e interfaces em muitos sistemas operacionais, incluindo DOS, Windows e NetWare:
- Exemplos
- As BIOS compatíveis com IBM PC usam os valores mágicos
00 00e12 34para decidir se o sistema deve ou não contar a memória na reinicialização, realizando assim um cold boot ou um warm boot. Esses valores também são usados pelos gerenciadores de memória EMM386 que interceptam requisições de boot. As BIOS também usam o valor mágico55 AApara determinar se um disco é inicializável. - O cache de disco SMARTDRV do MS-DOS (codinome "Bambi") usa os valores mágicos
BA BEeEB ABem funções de API. - Muitos drivers DR-DOS, Novell DOS e OpenDOS desenvolvidos no antigo European Development Centre no Reino Unido usam o valor
0E DCcomo token mágico ao invocar ou fornecer funcionalidades adicionais sobre as funções (emuladas) padrão do DOS, sendo o NWCACHE um exemplo.
Outros usos
- Exemplos
- O endereço MAC padrão nos SoCs da Texas Instruments é
DE:AD:BE:EF:00:00.
GUID
É possível criar ou alterar identificadores globalmente únicos (GUIDs) de modo que sejam memoráveis, mas isso é fortemente desaconselhado, pois compromete sua robustez como identificadores quase únicos. As especificações para gerar GUIDs e UUIDs são bastante complexas, o que é justamente o que faz com que sejam praticamente únicos, se implementadas corretamente.
Os números de ID de produto do Microsoft Windows para produtos do Microsoft Office às vezes terminam com 0000-0000-0000000FF1CE ("OFFICE"), como 90160000-008C-0000-0000-0000000FF1CE, o ID de produto do "Office 16 Click-to-Run Extensibility Component".
O Java usa vários GUIDs que começam com CAFEEFAC.
Na GUID Partition Table do esquema de particionamento GPT, as partições BIOS Boot usam o GUID especial 21686148-6449-6E6F-744E-656564454649, que não segue a definição de GUID; em vez disso, ele é formado usando os códigos ASCII da string Hah!IdontNeedEFI parcialmente em ordem little endian.
Valor de depuração
Os valores mágicos de depuração são valores específicos gravados na memória durante a alocação ou desalocação, de modo que seja possível, mais tarde, dizer se eles foram ou não corrompidos, e para tornar evidente quando valores obtidos de memória não inicializada estão sendo usados. A memória normalmente é visualizada em hexadecimal, de modo que valores repetidos memoráveis ou em hexspeak são comuns. Valores numericamente ímpares podem ser preferíveis para que processadores sem endereçamento por byte gerem uma falha ao tentar usá-los como ponteiros (que devem cair em endereços pares). Devem ser escolhidos valores afastados de endereços prováveis (o código do programa, dados estáticos, dados de heap ou a pilha). De forma semelhante, eles podem ser escolhidos de modo que não sejam códigos válidos no conjunto de instruções da arquitetura em questão.
Como é muito improvável, embora possível, que um inteiro de 32 bits assuma esse valor específico, o aparecimento de tal número em um depurador ou despejo de memória muito provavelmente indica um erro, como um estouro de buffer ou uma variável não inicializada.
Exemplos famosos e comuns incluem:
| Código | Descrição |
|---|---|
00008123 |
Usado no MS Visual C++. Ponteiros deletados são definidos com esse valor, de modo que lançam uma exceção quando usados depois; é um alias mais reconhecível para o endereço zero. É ativado com a opção Security Development Lifecycle (/sdl). |
..FACADE |
"Facade", usado por diversos RTOSes. |
1BADB002 |
"1 bad boot", número mágico do cabeçalho Multiboot. |
8BADF00D |
"Ate bad food", indica que um aplicativo iOS da Apple foi encerrado porque ocorreu um timeout do watchdog. |
A5A5A5A5 |
Usado no desenvolvimento de sistemas embarcados porque o padrão de bits alternados (1010 0101) cria um padrão facilmente reconhecível em osciloscópios e analisadores lógicos. |
A5 |
Usado no malloc(3) PHK do FreeBSD para depuração quando /etc/malloc.conf é apontado por symlink para "-J", a fim de inicializar toda a memória recém-alocada, já que esse valor não é um ponteiro NULL nem um caractere NUL ASCII. |
ABABABAB |
Usado pelo HeapAlloc() de depuração da Microsoft para marcar bytes de guarda de "terra de ninguém" após a memória de heap alocada. |
ABADBABE |
"A bad babe", usado pela Apple como o número mágico do "Boot Zero Block". |
ABBABABE |
"ABBA babe", usado pelo heap de memória de Driver: Parallel Lines. |
ABADCAFE |
"A bad cafe", usado para inicializar toda a memória não alocada (Mungwall, AmigaOS). |
B16B00B5 |
"Big Boobs", antigamente exigido pelo hypervisor Hyper-V da Microsoft para ser usado por convidados Linux como a metade superior de seu "guest id". |
BAADF00D |
"Bad food", usado pelo HeapAlloc() de depuração da Microsoft para marcar memória de heap alocada não inicializada. |
BAAAAAAD |
"Baaaaaad", indica que o log do iOS da Apple é um stackshot de todo o sistema, não um relatório de falha. |
BAD22222 |
"Bad too repeatedly", indica que um aplicativo VoIP iOS da Apple foi encerrado porque retomou com frequência excessiva. |
BADBADBADBAD |
"Bad bad bad bad", memória "não inicializada" dos Burroughs Large Systems (palavras de 48 bits). |
BADC0FFEE0DDF00D |
"Bad coffee odd food", usado em sistemas de 64 bits RS/6000 da IBM para indicar registradores de CPU não inicializados. |
BADDCAFE |
"Bad cafe", no Solaris da Sun Microsystems, marca memória de kernel não inicializada (KMEM_UNINITIALIZED_PATTERN). |
BBADBEEF |
"Bad beef", usado no WebKit, para erros particularmente irrecuperáveis. |
BEBEBEBE |
Usado pelo AddressSanitizer para preencher memória alocada, mas não inicializada. |
BEEFCACE |
"Beef cake", usado pelo Microsoft .NET como número mágico em arquivos de recursos. |
C00010FF |
"Cool off", indica que um app iOS da Apple foi encerrado pelo sistema operacional em resposta a um evento térmico. |
CAFEBABE |
"Cafe babe", usado pelo Java para arquivos de classe.
Usado em binários Mach-O multiarquitetura. |
CAFED00D |
"Cafe dude", usado pelo Java para sua compressão pack200. |
CAFEFEED |
"Cafe feed", usado pelo kernel de depuração do Solaris da Sun Microsystems para marcar memória de kmemfree(). |
CCCCCCCC |
Usado pela biblioteca de runtime de depuração C++ da Microsoft e por muitos ambientes DOS para marcar memória de pilha não inicializada. CC é o opcode da interrupção de breakpoint de depuração INT 3 em processadores x86.
|
CDCDCDCD |
Usado pela função malloc() de depuração C/C++ da Microsoft para marcar memória de heap não inicializada, normalmente retornada por HeapAlloc.
|
0D15EA5E |
"Zero Disease", usado como flag para indicar boot normal nos consoles GameCube e Wii. |
DDDDDDDD |
Usado pelo SmartHeap da MicroQuill e pela função free() de depuração C/C++ da Microsoft para marcar memória de heap liberada. |
DEAD10CC |
"Dead lock", indica que um aplicativo iOS da Apple foi encerrado porque manteve um recurso do sistema enquanto era executado em segundo plano. |
DEADBABE |
"Dead babe", usado no início dos arquivos arena do IRIX da Silicon Graphics. |
DEADBEEF |
"Dead beef", notoriamente usado em sistemas IBM, como o RS/6000, também usado nos sistemas operacionais Mac OS clássico, OPENSTEP Enterprise e no Amiga da Commodore. No Solaris da Sun Microsystems, marca memória de kernel liberada (KMEM_FREE_PATTERN). |
DEADCAFE |
"Dead cafe", usado pelo Microsoft .NET como um número de erro em DLLs. |
DEADC0DE |
"Dead code", usado como marcador no firmware OpenWRT para indicar o início do sistema de arquivos jffs2 a ser criado no fim do firmware estático. |
DEADFA11 |
"Dead fail", indica que um aplicativo iOS da Apple foi encerrado à força pelo usuário. |
DEADF00D |
"Dead food", usado pelo Mungwall no Amiga da Commodore para marcar memória alocada, mas não inicializada. |
DEFEC8ED |
"Defecated", usado para core dumps do OpenSolaris. |
DEADDEAD |
"Dead Dead" indica que o usuário iniciou deliberadamente um despejo de falha a partir do depurador de kernel ou do teclado no Microsoft Windows. |
D00D2BAD
|
"Dude, Too Bad", usado em falhas do Safari no macOS Big Sur. |
D00DF33D
|
"Dude feed", usado pela devicetree para marcar o início dos cabeçalhos. |
EBEBEBEB |
Do SmartHeap da MicroQuill. |
FADEDEAD |
"Fade dead", aparece no fim para identificar todo script AppleScript. |
FDFDFDFD |
Usado pela função malloc() de depuração C/C++ da Microsoft para marcar bytes de guarda de "terra de ninguém" antes e depois da memória de heap alocada, e algumas funções Secure C-Runtime de depuração implementadas pela Microsoft (p. ex. strncat_s). |
FEE1DEAD |
"Feel dead", usado pela syscall reboot() do Linux. |
FEEDFACE |
"Feed face", visto em binários Mach-O na plataforma Mac OSX da Apple Inc.. No Solaris da Sun Microsystems, marca a zona vermelha (KMEM_REDZONE_PATTERN).
Usado pelo VLC player e por algumas câmeras IP no protocolo RTP/RTCP; o VLC player envia quatro bytes na ordem da endianness do sistema. Algumas câmeras IP esperam que o player envie esse número mágico e não iniciam o stream se ele não for recebido. |
FEEEFEEE |
"Fee fee", usado pelo HeapFree() de depuração da Microsoft para marcar memória de heap liberada. Alguns valores internos de controle próximos também podem ter a palavra alta definida como FEEE. |
A maioria deles tem 32 bits de comprimento – o tamanho da palavra da maioria dos computadores de arquitetura de 32 bits.
A prevalência desses valores na tecnologia da Microsoft não é coincidência; eles são discutidos em detalhe no livro Writing Solid Code de Steve Maguire, da Microsoft Press. Ele apresenta uma variedade de critérios para esses valores, como:
- Eles não devem ser úteis; isto é, espera-se que a maioria dos algoritmos que operam sobre eles faça algo incomum. Números como zero não atendem a esse critério.
- Eles devem ser facilmente reconhecidos pelo programador como valores inválidos no depurador.
- Em máquinas que não têm alinhamento de bytes, eles devem ser números ímpares, de modo que desreferenciá-los como endereços cause uma exceção.
- Eles devem causar uma exceção, ou talvez até uma parada no depurador, se executados como código.
Como eram frequentemente usados para marcar áreas de memória essencialmente vazias, alguns desses termos passaram a ser usados em expressões com o sentido de "sumiu, abortou, foi descartado da memória"; p. ex. "Seu programa está DEADBEEF".