Магическое число (программирование)

Последовательность байтов, используемая для идентификации или указания формата файла.

В компьютерном программировании магическим числом является любое из следующих:

  • Уникальное значение с необъяснимым значением или многократное появление, которое можно (предпочтительно) заменить именованной константой
  • Постоянное числовое или текстовое значение, используемое для идентификации формата файла или протокола (для файлов см. Список сигнатур файлов ).
  • Отличительное уникальное значение, которое вряд ли будет ошибочно принято за другие значения (например, глобально уникальные идентификаторы ).

Неназванные числовые константы

Термин магическое число или магическая константа относится к анти-шаблону использования чисел непосредственно в исходном коде. Это было названо нарушением одного из старейших правил программирования, восходящего к руководствам COBOL , FORTRAN и PL/1 1960-х годов. [1] Использование неназванных магических чисел в коде скрывает намерение разработчиков при выборе этого числа, [2] увеличивает вероятность тонких ошибок (например, каждая ли цифра в числе 3,14159265358979323846 верна и может ли оно быть округлено до 3,14159? [ необходимо разъяснение ] [3] ) и затрудняет адаптацию и расширение программы в будущем. [4] Замена всех значимых магических чисел именованными константами (также называемыми пояснительными переменными) делает программы более простыми для чтения, понимания и поддержки. [5]

Имена, выбранные так, чтобы они были значимыми в контексте программы, могут привести к тому, что код будет легче понять сопровождающему, который не является первоначальным автором (или даже первоначальным автором по прошествии некоторого времени). [6] Примером неинформативно названной константы является int SIXTEEN = 16, тогда как int NUMBER_OF_BITS = 16является более описательным.

Проблемы, связанные с магическими «числами», описанные выше, не ограничиваются числовыми типами, и этот термин также применяется к другим типам данных, где объявление именованной константы было бы более гибким и коммуникативным. [1] Таким образом, объявление const string testUserName = "John"лучше, чем несколько вхождений «магического значения» "John"в тестовом наборе .

Например, если требуется случайным образом перетасовать значения в массиве, представляющем стандартную колоду игральных карт , этот псевдокод выполнит эту работу, используя алгоритм тасования Фишера-Йетса :

для i от 1 до 52 j := i + randomInt(53 - i) - 1 а.swapEntries(i, j)

где a— объект массива, функция randomInt(x)выбирает случайное целое число от 1 до x включительно и swapEntries(i, j)меняет местами i -ю и j -ю записи в массиве. В предыдущем примере 52и 53— магические числа, также явно не связанные друг с другом. Считается лучшим стилем программирования написать следующее:

int deckSize:= 52 для i от 1 до deckSize j := i + randomInt(deckSize + 1 - i) - 1 а.swapEntries(i, j)

Это предпочтительнее по нескольким причинам:

  • Его легче читать и понимать. Программист, читающий первый пример, может задаться вопросом: «Что здесь означает число 52? Почему 52?» Программист может догадаться об этом значении, внимательно прочитав код, но оно не очевидно. [6] Магические числа становятся особенно запутанными, когда одно и то же число используется для разных целей в одном разделе кода.
  • Значение числа изменить проще, так как оно не дублируется. Изменение значения магического числа подвержено ошибкам, поскольку одно и то же значение часто используется несколько раз в разных местах программы. [6] Кроме того, когда две семантически различные переменные или числа имеют одно и то же значение, они могут быть случайно отредактированы вместе. [6] Чтобы изменить первый пример для перетасовки колоды Таро , в которой 78 карт, программист может наивно заменить все экземпляры 52 в программе на 78. Это вызовет две проблемы. Во-первых, он пропустит значение 53 во второй строке примера, что приведет к скрытому сбою алгоритма. Во-вторых, он, скорее всего, заменит символы «52» везде, независимо от того, относятся ли они к размеру колоды или к чему-то совершенно другому, например, к количеству недель в году по григорианскому календарю, или, что более коварно, являются частью числа, например, «1523», что приведет к ошибкам. Напротив, изменение значения переменной deckSizeво втором примере будет простым изменением в одну строку.
  • Это поощряет и облегчает документирование. [6] Единственное место, где объявляется именованная переменная, является хорошим местом для документирования того, что означает значение и почему оно имеет то значение, которое имеет. Наличие одного и того же значения во множестве мест либо приводит к дублированию комментариев (и сопутствующим проблемам при обновлении некоторых и пропуске некоторых) или не оставляет ни одного места, где было бы естественно для автора объяснить значение, а читатель, вероятно, будет искать объяснение.
  • Объявления переменных «магического числа» размещаются вместе, обычно в верхней части функции или файла, что облегчает их просмотр и изменение. [6]
  • Это помогает обнаружить опечатки . Использование переменной (вместо литерала) использует проверку компилятора. Случайный ввод "62" вместо "52" останется незамеченным, тогда как ввод " dekSize" вместо " deckSize" приведет к предупреждению компилятора о том, что dekSizeне объявлено.
  • Это может сократить набор текста в некоторых IDE . Если IDE поддерживает автодополнение кода , она заполнит большую часть имени переменной из первых нескольких букв.
  • Это облегчает параметризацию. Например, чтобы обобщить приведенный выше пример в процедуру, которая перетасовывает колоду из любого количества карт, достаточно превратить deckSizeв параметр этой процедуры, тогда как первый пример потребовал бы нескольких изменений.
функция shuffle ( int deckSize) для i от 1 до deckSize j := i + randomInt(deckSize + 1 - i) - 1 а.swapEntries(i, j)

Недостатки:

  • Когда именованная константа не определена вблизи ее использования, это вредит локальности и, следовательно, понятности кода. Размещение 52 в возможно отдаленном месте означает, что для полного понимания работы цикла "for" (например, для оценки времени выполнения цикла) необходимо отследить определение и убедиться, что это ожидаемое число. Этого легко избежать (переместив объявление), когда константа используется только в одной части кода. С другой стороны, когда именованная константа используется в разрозненных частях, отдаленное расположение является подсказкой для читателя, что то же самое значение появляется в других местах кода, что также может быть полезным.
  • Это может сделать код более многословным. Объявление константы добавляет строку. Когда имя константы длиннее значения, особенно если несколько таких констант появляются в одной строке, это может привести к необходимости разбить один логический оператор кода на несколько строк. Увеличение многословия может быть оправдано, когда есть некоторая вероятность путаницы относительно константы, или когда есть вероятность, что константу может потребоваться изменить, например, повторное использование процедуры тасования для других карточных игр. Это может быть в равной степени оправдано как увеличение выразительности.
  • Обработка выражения deckSize + 1во время выполнения может быть медленнее, чем обработка значения "53", хотя большинство современных компиляторов и интерпретаторов заметят, что оно deckSizeбыло объявлено как константа, и предварительно вычислят значение 53 в скомпилированном коде. Даже если это невозможно, оптимизация цикла переместит сложение так, чтобы оно выполнялось до цикла. Поэтому обычно нет (или незначительно) потери скорости по сравнению с использованием магических чисел в коде. Особенно стоимость отладки и время, необходимое для понимания непояснительного кода, должны быть сопоставлены с крошечной стоимостью вычислений.

Принятые виды использования

В некоторых контекстах использование неназванных числовых констант является общепринятым (и, возможно, «не магическим»). Хотя такое принятие субъективно и часто зависит от индивидуальных привычек кодирования, ниже приведены распространенные примеры:

  • использование 0 и 1 в качестве начальных или инкрементных значений в цикле for , напримерfor (int i = 0; i < max; i += 1)
  • использование 2 для проверки того, является ли число четным или нечетным, как в isEven = (x % 2 == 0), где %есть оператор по модулю
  • использование простых арифметических констант, например, в выражениях типа circumference = 2 * Math.PI * radius, [1] или для вычисления дискриминанта квадратного уравнения какd = b^2 − 4*a*c
  • использование степеней числа 10 для преобразования метрических величин (например, между граммами и килограммами) или для вычисления значений процентов и промилле
  • показатели степени в выражениях, таких (f(x) ** 2 + f(y) ** 2) ** 0.5как ф ( х ) 2 + ф ( у ) 2 {\displaystyle {\sqrt {f(x)^{2}+f(y)^{2}}}}

Константы 1 и 0 иногда используются для представления булевых значений true и false в языках программирования без булевого типа, таких как старые версии C. Большинство современных языков программирования предоставляют примитивный типboolean или , поэтому использование 0 и 1 нецелесообразно. Это может быть еще более запутанным, поскольку 0 иногда означает программный успех (когда -1 означает неудачу) и неудачу в других случаях (когда 1 означает успех).bool

В C и C++ 0 представляет нулевой указатель . Как и в случае с булевыми значениями, стандартная библиотека C включает определение макроса NULL, использование которого поощряется. Другие языки предоставляют определенное значение nullor nil, и в этом случае не следует использовать альтернативу. Типизированная константа указателя nullptrбыла введена в C++11.

Индикаторы формата

Источник

Индикаторы формата впервые были использованы в исходном коде ранней версии 7 Unix . [ необходима ссылка ]

Unix был перенесен на один из первых DEC PDP-11 /20, который не имел защиты памяти . Поэтому ранние версии Unix использовали модель перемещаемой ссылки памяти . [7] Версии Unix до шестого издания считывали исполняемый файл в память и переходили на первый нижний адрес памяти программы, относительный адрес ноль. С развитием страничных версий Unix был создан заголовок для описания компонентов исполняемого образа . Кроме того, инструкция ветвления была вставлена ​​как первое слово заголовка, чтобы пропустить заголовок и запустить программу. Таким образом, программа могла быть запущена в старом режиме перемещаемой ссылки памяти (обычном) или в страничном режиме. По мере разработки большего количества исполняемых форматов новые константы добавлялись путем увеличения смещения ветвления . [8]

В исходном коде шестого издания загрузчика программ Unix функция exec() считывала исполняемый ( двоичный ) образ из файловой системы. Первые 8 байт файла были заголовком , содержащим размеры программной (текстовой) и инициализированных (глобальных) областей данных. Кроме того, первое 16-битное слово заголовка сравнивалось с двумя константами , чтобы определить, содержит ли исполняемый образ перемещаемые ссылки на память (обычные), недавно реализованный исполняемый образ с подкачкой только для чтения или разделенный образ инструкции и данных с подкачкой. [9] Не было никакого упоминания о двойной роли константы заголовка, но старший байт константы был, по сути, кодом операции для инструкции ветвления PDP-11 ( восьмеричное 000407 или шестнадцатеричное 0107). Добавление семи к счетчику программ показало, что если эта константа была выполнена , она перейдет к службе Unix exec() по восьмибайтовому заголовку исполняемого образа и запустит программу.

Поскольку шестое и седьмое издания Unix использовали код подкачки, двойная роль константы заголовка была скрыта. То есть, служба exec() считывала данные заголовка исполняемого файла ( meta ) в буфер пространства ядра , но считывала исполняемый образ в пространство пользователя , тем самым не используя функцию ветвления константы. Создание магических чисел было реализовано в компоновщике и загрузчике Unix , а ветвление магических чисел, вероятно, все еще использовалось в наборе автономных диагностических программ , которые поставлялись с шестым и седьмым изданиями. Таким образом, константа заголовка действительно создавала иллюзию и соответствовала критериям magic .

В седьмой версии Unix константа заголовка не проверялась напрямую, а была назначена переменной с меткой ux_mag [10] и впоследствии упоминалась как магическое число . Вероятно, из-за своей уникальности термин магическое число стал обозначать тип исполняемого формата, затем был расширен до типа файловой системы и снова расширен до любого типа файла.

В файлах

Магические числа распространены в программах во многих операционных системах. Магические числа реализуют строго типизированные данные и являются формой внутриполосной сигнализации для управляющей программы, которая считывает тип(ы) данных во время выполнения программы. Многие файлы имеют такие константы, которые идентифицируют содержащиеся данные. Обнаружение таких констант в файлах является простым и эффективным способом различения многих форматов файлов и может дать дополнительную информацию во время выполнения .

Примеры
Обнаружение

Утилитная программа Unix fileможет считывать и интерпретировать магические числа из файлов, а файл, который используется для анализа информации, называется magic . Утилита Windows TrID имеет схожее назначение.

В протоколах

Примеры
  • Протокол OSCAR , используемый в AIM / ICQ , добавляет к запросам префикс 2A.
  • В протоколе RFB, используемом VNC , клиент начинает свой диалог с сервером, отправляя «RFB» ( 52 46 42от «Remote Frame Buffer»), за которым следует номер версии протокола клиента.
  • В протоколе SMB , используемом Microsoft Windows, каждый запрос SMB или ответ сервера начинается с « FF 53 4D 42» или "\xFFSMB"с начала запроса SMB.
  • В протоколе MSRPC, используемом Microsoft Windows, каждый запрос на основе TCP начинается с 05начала запроса (представляющего Microsoft DCE/RPC версии 5), за которым сразу следует 00или 01для младшей версии. В запросах MSRPC на основе UDP первый байт всегда 04.
  • В COM и DCOM маршаллированные интерфейсы, называемые OBJREF , всегда начинаются с последовательности байтов "MEOW" ( 4D 45 4F 57). Отладочные расширения (используемые для перехвата канала DCOM) начинаются с последовательности байтов "MARB" ( 4D 41 52 42).
  • Незашифрованные запросы трекера BitTorrent начинаются с одного байта, содержащего значение 19, представляющее длину заголовка, за которым сразу следует фраза «протокол BitTorrent» в позиции байта 1.
  • Трафик eDonkey2000 / eMule начинается с одного байта, представляющего версию клиента. В настоящее время E3представляет клиента eDonkey, C5представляет eMule и D4представляет сжатый eMule.
  • Первые 4 байта блока в блокчейне Bitcoin содержат магическое число, которое служит идентификатором сети. Значение является константой 0xD9B4BEF9, которая указывает на основную сеть, в то время как константа 0xDAB5BFFAуказывает на тестовую сеть.
  • SSL- транзакции всегда начинаются с сообщения "client hello". Схема инкапсуляции записей, используемая для префикса всех SSL-пакетов, состоит из двух- и трехбайтовых заголовков. Обычно клиентское приветственное сообщение SSL версии 2 имеет префикс 80, а ответ сервера SSLv3 на клиентское приветствие начинается с 16(хотя это может отличаться).
  • Пакеты DHCP используют значение "волшебного куки" ' 0x63 0x82 0x53 0x63' в начале раздела опций пакета. Это значение включено во все типы пакетов DHCP.
  • Соединения HTTP/2 открываются с префиксом ' 0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a' или " PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n". Префикс предназначен для того, чтобы избежать обработки фреймов серверами и посредниками, которые поддерживают более ранние версии HTTP, но не 2.0.

В интерфейсах

Магические числа широко распространены в функциях и интерфейсах API многих операционных систем , включая DOS , Windows и NetWare :

Примеры
  • BIOS, совместимые с IBM PC, используют магические значения 0000и 1234решают, следует ли системе подсчитывать память или нет при перезагрузке, тем самым выполняя холодную или горячую загрузку. Эти значения также используются менеджерами памяти EMM386, перехватывающими запросы на загрузку. [13] BIOS также используют магические значения 55 AAдля определения того, является ли диск загрузочным. [14]
  • Дисковый кэш MS -DOS SMARTDRV (кодовое название «Bambi») использует магические значения BABE и EBAB в функциях API. [13]
  • Многие драйверы DR DOS , Novell DOS и OpenDOS, разработанные в бывшем Европейском центре разработки в Великобритании, используют значение 0EDC в качестве магического токена при вызове или предоставлении дополнительных функций, расположенных поверх (эмулируемых) стандартных функций DOS, одним из примеров является NWCACHE. [13]

Другие применения

Примеры
  • MAC-адрес по умолчанию на Texas Instruments SOC — DE:AD:BE:EF:00:00. [15]

Ограничения по типу данных

Это список ограничений типов хранения данных: [16]

Десятичная дробьШестигранникОписание
18,446,744,073,709,551,615ФФФ ФФФ ФФФ ФФФМаксимальное беззнаковое 64-битное значение (2 64 − 1)
9,223,372,036,854,775,8077ФФФ ФФФФ ФФФФ ФФФМаксимальное знаковое 64-битное значение (2 63 − 1)
9,007,199,254,740,9920020 0000 0000 0000Наибольшее последовательное целое число двойной точности IEEE 754 (2 53 )
4,294,967,295ФФФФ ФФФМаксимальное беззнаковое 32-битное значение (2 32 − 1)
2,147,483,6477ФФФ ФФФФМаксимальное знаковое 32-битное значение (2 31 − 1)
16,777,2160100 0000Наибольшее последовательное целое число одинарной точности IEEE 754 (2 24 )
65,535ФФФФМаксимальное беззнаковое 16-битное значение (2 16 − 1)
32,7677ФФФМаксимальное знаковое 16-битное значение (2 15 − 1)
255ФФМаксимальное беззнаковое 8-битное значение (2 8 − 1)
127Максимальное знаковое 8-битное значение (2 7 − 1)
−12880Минимальное 8-битное значение со знаком
−32,7688000Минимальное 16-битное значение со знаком
−2,147,483,6488000 0000Минимальное 32-битное значение со знаком
−9,223,372,036,854,775,8088000 0000 0000 0000Минимальное 64-битное значение со знаком

GUID-ы

Можно создавать или изменять глобально уникальные идентификаторы (GUID) так, чтобы они были запоминающимися, но это крайне не рекомендуется, поскольку это ставит под угрозу их силу как почти уникальных идентификаторов. [17] [18] Спецификации для генерации GUID и UUID довольно сложны, что приводит к тому, что они фактически уникальны, если реализованы правильно. [19]

Номера идентификаторов продуктов Microsoft Windows для продуктов Microsoft Office иногда заканчиваются на 0000-0000-0000000FF1CE(«OFFICE»), например { 90160000-008C-0000-0000-0000000FF1CE}, идентификатор продукта для «Компонента расширяемости Office 16 Click-to-Run».

Java использует несколько GUID, начинающихся с CAFEEFAC. [20]

В таблице разделов GUID схемы разбиения GPT загрузочные разделы BIOS используют специальный GUID { 21686148-6449-6E6F-744E-656564454649} [21] , который не следует определению GUID; вместо этого он формируется с использованием кодов ASCII для строки " Hah!IdontNeedEFI" частично в прямом порядке байтов . [22]

Отладочные значения

Значения магической отладки — это определенные значения, записываемые в память во время выделения или освобождения, чтобы впоследствии можно было определить, были ли они повреждены, и сделать очевидным, когда используются значения, взятые из неинициализированной памяти. Память обычно отображается в шестнадцатеричном формате, поэтому часто встречаются запоминающиеся повторяющиеся или шестнадцатеричные значения. Численно нечетные значения могут быть предпочтительными, чтобы процессоры без байтовой адресации выдавали ошибку при попытке использовать их в качестве указателей (которые должны попадать на четные адреса). Значения следует выбирать так, чтобы они находились вдали от вероятных адресов (код программы, статические данные, данные кучи или стек). Аналогично их можно выбирать так, чтобы они не были допустимыми кодами в наборе инструкций для данной архитектуры.

Поскольку маловероятно, хотя и возможно, что 32-разрядное целое число примет это конкретное значение, появление такого числа в отладчике или дампе памяти, скорее всего, указывает на ошибку, например, переполнение буфера или неинициализированную переменную .

Известные и распространённые примеры включают в себя:

КодОписание
00008123Используется в MS Visual C++. Удаленные указатели устанавливаются в это значение, поэтому они выдают исключение, когда используются после; это более узнаваемый псевдоним для нулевого адреса. Он активируется с помощью параметра Security Development Lifecycle (/sdl). [23]
..FACADE«Фасад» , используется рядом ОСРВ
1BADB002"1 плохая загрузка" , магическое число заголовка мультизагрузки [24]
8BADF00D«Съел плохую еду» . Указывает, что приложение Apple iOS было завершено из-за истечения времени ожидания сторожевого таймера. [25]
A5A5A5A5Используется при разработке встраиваемых систем, поскольку чередующаяся последовательность битов (1010 0101) создает легко распознаваемый шаблон на осциллографах и логических анализаторах .
A5Используется в PHK malloc(3) FreeBSD для отладки, когда /etc/malloc.conf имеет символическую ссылку на "-J" для инициализации всей вновь выделенной памяти, поскольку это значение не является указателем NULL или символом ASCII NUL.
ABABABABИспользуется отладочной функцией HeapAlloc() от Microsoft для маркировки байтов защиты «нейтральной зоны» после выделения памяти кучи. [26]
ABADBABE«Плохая малышка» , используется Apple как магическое число «Boot Zero Block»
ABBABABE« ABBA babe» , используется кучей памяти Driver Parallel Lines .
ABADCAFE«Плохое кафе» , используется для инициализации всей нераспределенной памяти (Mungwall, AmigaOS )
B16B00B5«Big Boobs» — ранее требовалось гипервизором Microsoft Hyper -V для использования гостями Linux в качестве верхней половины их «гостевого идентификатора» [27]
BAADF00D«Плохая еда» , используется отладочной функцией HeapAlloc() от Microsoft для маркировки неинициализированной выделенной памяти кучи [26]
BAAAAAAD"Baaaaaad" , Указывает, что журнал Apple iOS представляет собой снимок всей системы, а не отчет о сбое [25]
BAD22222«Плохо слишком часто» — указывает на то, что приложение Apple iOS VoIP было завершено из-за слишком частого возобновления работы [25]
BADBADBADBAD"Плохо, плохо, плохо" , "неинициализированная" память больших систем Берроуза (48-битные слова)
BADC0FFEE0DDF00D«Bad coffee odd food» — используется в 64-битных системах IBM RS/6000 для обозначения неинициализированных регистров ЦП.
BADDCAFE«Bad cafe» в ОС Solaris от Sun Microsystems обозначает неинициализированную память ядра (KMEM_UNINITIALIZED_PATTERN)
BBADBEEF«Плохая говядина» , используется в WebKit для особо неисправимых ошибок [28]
BEBEBEBEИспользуется AddressSanitizer для заполнения выделенной, но не инициализированной памяти [29]
BEEFCACE«Говяжий пирог» , используется Microsoft .NET как магическое число в файлах ресурсов
C00010FF«Cool off» — указывает на то, что приложение Apple iOS было закрыто операционной системой в ответ на температурное событие [25]
CAFEBABE"Cafe babe" , используется Java для файлов классов
CAFED00D"Cafe dude" , используется Java для сжатия pack200
CAFEFEED«Cafe feed» , используется ядром отладки Solaris компании Sun Microsystems для маркировки памяти kmemfree()
CCCCCCCCИспользуется библиотекой отладки C++ Microsoft и многими средами DOS для маркировки неинициализированной памяти стека . CCЭто код операции прерывания отладочной точки останова INT 3 на процессорах x86. [30]
CDCDCDCDИспользуется отладочной функцией Microsoft C/C++ malloc() для маркировки неинициализированной памяти кучи, обычно возвращается из HeapAlloc() [26]
0D15EA5E«Zero Disease» — используется как флаг для обозначения обычной загрузки на консолях GameCube и Wii .
DDDDDDDDИспользуется функцией MicroQuill SmartHeap и функцией отладки Microsoft C/C++ free() для маркировки освобожденной памяти кучи [26]
DEAD10CC«Всё заблокировано» . Указывает на то, что приложение Apple iOS было завершено, поскольку оно удерживало системный ресурс во время работы в фоновом режиме [25]
DEADBABE«Dead babe» , используется в начале файлов Silicon Graphics IRIX arena
DEADBEEF"Dead beef" , широко используемый в системах IBM , таких как RS/6000 , также используемый в классических операционных системах Mac OS , OPENSTEP Enterprise и Commodore Amiga . В Solaris от Sun Microsystems , обозначает освобожденную память ядра (KMEM_FREE_PATTERN)
DEADCAFE«Dead cafe» — используется Microsoft .NET как номер ошибки в библиотеках DLL.
DEADC0DE«Мертвый код» . Используется в качестве маркера в прошивке OpenWRT для обозначения начала создаваемой файловой системы jffs2 в конце статической прошивки.
DEADFA11«Полный сбой» . Указывает, что приложение Apple iOS было принудительно закрыто пользователем [25]
DEADF00D«Мертвая еда» , использовалась Mungwall на Commodore Amiga для обозначения выделенной, но неинициализированной памяти [31]
DEFEC8ED"Defeated" , используется для дампов ядра OpenSolaris
DEADDEAD«Dead Dead» означает, что пользователь намеренно инициировал аварийный дамп либо из отладчика ядра, либо с клавиатуры в Microsoft Windows. [32]
D00D2BAD«Dude, Too Bad», используемый Safari, приводит к сбоям в работе macOS Big Sur. [33]
D00DF33D«Dude feed», используется devicetree для обозначения начала заголовков. [34]
EBEBEBEBИз SmartHeap от MicroQuill
FADEDEAD"Fade dead" , идет в конце, чтобы идентифицировать каждый скрипт AppleScript
FDFDFDFDИспользуется отладочной функцией malloc() от Microsoft C/C++ для маркировки байтов защиты «нейтральной зоны» до и после выделенной динамической памяти [26] и некоторыми отладочными функциями Secure C-Runtime, реализованными Microsoft (например, strncat_s) [35]
FEE1DEAD«Feel dead» — используется системным вызовом Linux reboot()
FEEDFACE"Feed face" , встречается в двоичных файлах PowerPC Mach-O на платформе Mac OSX компании Apple Inc. В Solaris компании Sun Microsystems обозначает красную зону (KMEM_REDZONE_PATTERN)

Используется проигрывателем VLC и некоторыми IP-камерами в протоколе RTP / RTCP , проигрыватель VLC отправляет четыре байта в порядке порядка байтов системы. Некоторые IP-камеры ожидают, что проигрыватель отправит это магическое число, и не начинают поток, если оно не получено.

FEEEFEEE"Fee fee" , используется отладочной функцией HeapFree() от Microsoft для маркировки освобожденной памяти кучи. Некоторые близлежащие внутренние значения учета могут также иметь верхнее слово, установленное на FEEE. [26]

Большинство из них имеют длину 32 битаразмер слова большинства компьютеров с 32-битной архитектурой.

Распространенность этих ценностей в технологиях Microsoft не является совпадением; они подробно обсуждаются в книге Стива Магуайра Writing Solid Code from Microsoft Press . Он приводит ряд критериев для этих ценностей, таких как:

  • Они не должны быть полезными; то есть, большинство алгоритмов, которые работают с ними, должны делать что-то необычное. Такие числа, как ноль, не подходят под этот критерий.
  • Программист должен легко распознать их как недопустимые значения в отладчике.
  • На машинах, не имеющих выравнивания байтов , они должны быть нечетными числами , чтобы разыменование их как адресов вызывало исключение.
  • Они должны вызывать исключение или, возможно, даже остановку отладчика, если выполняются как код.

Поскольку они часто использовались для обозначения областей памяти, которые были по сути пустыми, некоторые из этих терминов стали использоваться во фразах, означающих «исчез, прерван, стерт из памяти»; например, «Ваша программа DEADBEEF». [ необходима цитата ]

Смотрите также

Ссылки

  1. ^ abc Martin, Robert C. (2009). "Глава 17: Запахи и эвристики - G25 Замена магических чисел именованными константами". Чистый код - Справочник по гибкому программному мастерству . Бостон: Prentice Hall. стр. 300. ISBN 978-0-13-235088-4.
  2. ^ Мартин, Роберт С. (2009). "Глава 17: Запахи и эвристики - G16 Obscured Intent". Чистый код - Справочник по гибкому программному мастерству . Бостон: Prentice Hall. стр. 295. ISBN 978-0-13-235088-4.
  3. ^ Контьери, Макси (2020-10-20). "Code Smell 02 - Константы и магические числа". Максимилиано Контьери - Разработка программного обеспечения . Получено 2024-03-21 .
  4. ^ Магуайр, Джеймс (2008-12-09). "Бьярн Страуструп об обучении разработчиков программного обеспечения". Datamation.com . Архивировано из оригинала 2018-06-23.
  5. ^ Фогель, Джефф (29.05.2007). «Шесть способов писать более понятный код». IBM Developer . Архивировано из оригинала 26.09.2018.
  6. ^ abcdef Пол, Маттиас Р. (2002-04-09). "[fd-dev] CuteMouse 2.0 alpha 1". freedos-dev . Архивировано из оригинала 2022-04-07 . Получено 2022-08-04 .
  7. ^ "Странные комментарии и странные дела в Unix". Bell Labs . 2002-06-22. Архивировано из оригинала 2006-11-04.
  8. Личное общение с Деннисом М. Ричи.
  9. ^ "The Unix Tree V6/usr/sys/ken/sys1.c". The Unix Heritage Society . Архивировано из оригинала 2023-03-26.
  10. ^ "The Unix Tree V7/usr/sys/sys/sys1.c". The Unix Heritage Society . Архивировано из оригинала 2023-03-26.
  11. ^ "Спецификация PNG (переносимая сетевая графика) версии 1.0: 12.11. Подпись файла PNG". MIT . 1996-10-01. Архивировано из оригинала 2023-03-26.
  12. ^ Чен, Рэймонд (2008-03-24). "В чем разница между расширениями COM и EXE?". The Old New Thing . Архивировано из оригинала 2019-02-18.
  13. ^ abc Пол, Маттиас Р. (2002-04-03). "[fd-dev] Ctrl+Alt+Del". freedos-dev . Архивировано из оригинала 2017-09-09 . Получено 2017-09-09 .(Примечание. Упоминается ряд магических значений, используемых IBM PC -совместимыми BIOS (0000h, 1234h), менеджерами памяти DOS , такими как EMM386 (1234h), и дисковыми кэшами, такими как SMARTDRV (EBABh, BABEh) и NWCACHE (0EDCh, EBABh, 6756h).)
  14. ^ "Процесс загрузки BIOS/MBR". База знаний NeoSmart . 2015-01-25. Архивировано из оригинала 2023-03-26 . Получено 2019-02-03 .
  15. ^ «Сообщество TI E2E: кто-нибудь знает, можно ли выполнить следующие конфигурации с помощью инструмента MCP CLI?». Texas Instruments . 2011-08-27. Архивировано из оригинала 2022-10-07.
  16. ^ Поли, Джош (2009-09-30). "Волшебные числа: целые числа". Learn . Microsoft . Архивировано из оригинала 2023-03-28.
  17. ^ Newcomer, Joseph M. (2001-10-13). "Message Management: Guaranteeing uniqueness". Developer Fusion . Архивировано из оригинала 2005-04-21 . Получено 2007-11-16 .
  18. ^ Остерман, Ларри (21.07.2005). «UUID уникальны только если вы их генерируете...» Веб-журнал Ларри Остермана — Признания старого чудака . MSDN. Архивировано из оригинала 28.03.2023 . Получено 16.11.2007 .
  19. ^ "RFC 9562 - Универсально уникальные идентификаторы (UUID)". ietf.org . Май 2024 . Получено 2024-08-09 .
  20. ^ "Развертывание Java-апплетов с версиями JRE семейства в подключаемом модуле Java для Internet Explorer". Oracle . Архивировано из оригинала 2022-11-30 . Получено 2023-03-28 .
  21. ^ "Установка GNU GRUB, раздел 3.4: Установка BIOS". Gnu.org . Архивировано из оригинала 2023-03-15 . Получено 2014-06-26 .
  22. ^ Хеддингс, Лоуэлл (2014-11-03). "Магические числа: секретные коды, которые программисты скрывают на вашем ПК". How-To Geek . Архивировано из оригинала 2023-03-26 . Получено 2017-10-03 .
  23. ^ Cavit, Doug (2012-04-24). «Защита от повторного использования устаревших ссылок на объекты». Microsoft Secure . Архивировано из оригинала 2018-07-26 . Получено 2018-07-26 .
  24. ^ Болейн, Эрих Стефан (1995-04-04). "Комментарии к предложению 'MultiBoot Standard'". Uruk.org . Архивировано из оригинала 2023-03-26.
  25. ^ abcdef "Техническое примечание TN2151: Понимание и анализ отчетов о сбоях приложений". Документация разработчиков Apple . 2009-01-29. Архивировано из оригинала 2018-12-13.
  26. ^ abcdef Биркетт, Эндрю. "Внутреннее устройство кучи Win32 Debug CRT". Nobugs.org .
  27. ^ Макнамара, Пол (2012-07-19). «Код Microsoft содержит фразу „большие сиськи“... Да, действительно». Network World .
  28. ^ WebKit, проект с открытым исходным кодом WebKit, 2023-01-06 , получено 2023-01-06
  29. ^ "AddressSanitizer - FAQ". GitHub . Получено 2022-05-18 .
  30. ^ "СПРАВОЧНОЕ РУКОВОДСТВО ПРОГРАММИСТА INTEL 80386". MIT .
  31. ^ Шеппнер, Кэролин. "Amiga Mail Vol.2 Guide". Cataclysm.cx . Архивировано из оригинала 2011-07-18 . Получено 2010-08-20 .
  32. ^ "Проверка ошибки 0xDEADDEAD MANUALLY_INITIATED_CRASH1". Документация Microsoft . 2023-06-19.
  33. ^ «Safari версии 14.0.1 неожиданно завершает работу».
  34. ^ «Спецификация дерева устройств».
  35. ^ "strncat_s, _strncat_s_l, wcsncat_s, _wcsncat_s_l, _mbsncat_s, _mbsncat_s_l". Документация Microsoft . Получено 2019-01-16 .
Взято с "https://en.wikipedia.org/w/index.php?title=Magic_number_(programming)&oldid=1265780141"