В компьютерном программировании термин « магическое число» имеет несколько значений. Это может относиться к одному или нескольким из следующего:
Термин « магическое число» или « магическая константа» относится к анти-шаблону использования чисел непосредственно в исходном коде. Это было названо нарушением одного из старейших правил программирования, восходящего к руководствам по COBOL, FORTRAN и PL / 1 1960-х годов. Использование безымянных магических чисел в коде скрывает намерение разработчиков при выборе этого числа, увеличивает возможности для незначительных ошибок (например, правильна ли каждая цифра в 3.14159265358979323846 и равно ли это 3,14159?) И затрудняет адаптацию программы. и расширен в будущем. Замена всех значащих магических чисел именованными константами упрощает чтение, понимание и сопровождение программ.
Имена, выбранные как значимые в контексте программы, могут привести к тому, что код будет легче понять сопровождающему, который не является первоначальным автором (или даже первоначальным автором по прошествии некоторого времени). Пример uninformatively названия проницаемости int SIXTEEN = 16
, в то время как int NUMBER_OF_BITS = 16
более описательный характер.
Проблемы, связанные с магическими «числами», описанными выше, не ограничиваются числовыми типами, и этот термин также применяется к другим типам данных, где объявление именованной константы было бы более гибким и коммуникативным. Таким образом, объявление const string testUserName = "John"
лучше, чем несколько вхождений «магического значения» "John"
в набор тестов.
Например, если требуется случайным образом перемешать значения в массиве, представляющем стандартную колоду игральных карт, этот псевдокод выполняет эту работу, используя алгоритм перемешивания Фишера – Йейтса :
for i from 1 to 52 j := i + randomInt(53 - i) - 1 a.swapEntries(i, j)
где a
- объект массива, функция randomInt(x)
выбирает случайное целое число от 1 до x включительно и swapEntries(i, j)
меняет местами i- ю и j- ю записи в массиве. В предыдущем примере 52
- это магическое число. Считается лучшим стилем программирования написать следующее:
constant int deckSize := 52 for i from 1 to deckSize j := i + randomInt(deckSize + 1 - i) - 1 a.swapEntries(i, j)
Это предпочтительно по нескольким причинам:
deckSize
переменной во втором примере будет простым изменением в одну строку.deckSize
в параметр этой процедуры, тогда как первый пример потребует нескольких изменений.function shuffle (int deckSize) for i from 1 to deckSize j := i + randomInt(deckSize + 1 - i) - 1 a.swapEntries(i, j)
dekSize
» вместо « deckSize
» приведет к dekSize
необъявленному предупреждению компилятора.Недостатки:
deckSize + 1
во время выполнения может быть медленнее, чем значение «53», хотя большинство современных компиляторов и интерпретаторов заметят, что deckSize
оно было объявлено как константа, и предварительно вычисят значение 53 в скомпилированном коде. Даже если это не вариант, оптимизация цикла переместит добавление так, чтобы оно выполнялось перед циклом. Поэтому обычно нет (или незначительно) потери скорости по сравнению с использованием магических чисел в коде.В некоторых контекстах общепринято использование безымянных числовых констант (и, возможно, «не магия»). Хотя такое принятие является субъективным и часто зависит от индивидуальных привычек программирования, ниже приведены общие примеры:
for (int i = 0; i lt; max; i += 1)
isEven = (x % 2 == 0)
, где %
- оператор по модулю circumference = 2 * Math.PI * radius
, или для вычисления дискриминанта в виде квадратного уравнения какd = b^2 − 4*a*c
(f(x) ** 2 + f(y) ** 2) ** 0.5
дляКонстанты 1: 0 и иногда используются для представления булевых значений истины и лжи в языках программирования без логического типа, таких как более старых версии C. Большинство современных языков программирования обеспечивают boolean
или bool
примитивный тип и поэтому использование 0 и 1 опрометчиво. Это может сбивать с толку, поскольку 0 иногда означает программный успех (когда -1 означает неудачу) и неудачу в других случаях (когда 1 означает успех).
В C и C ++ для представления нулевого указателя иногда используется 0. Как и в случае с логическими значениями, стандартная библиотека C включает определение макроса NULL
, использование которого приветствуется. Другие языки предоставляют конкретное значение null
или, nil
и в этом случае не следует использовать альтернативу. Константа типизированного указателя nullptr
была введена в C ++ 11.
Индикаторы формата были впервые использованы в исходном коде Unix ранней версии 7.
Unix был портирован на один из первых DEC PDP-11 /20, не имевший защиты памяти. Поэтому в ранних версиях Unix использовалась эталонная модель перемещаемой памяти. Пред- шестого издания Unix версия прочитать исполняемый файл в память и прыгнула на первый низкий адрес памяти программы, относительный адрес нулевого. С развитием страничных версий Unix был создан заголовок для описания компонентов исполняемого образа. Кроме того, в качестве первого слова заголовка была вставлена инструкция ветвления, чтобы пропустить заголовок и запустить программу. Таким образом, программа могла быть запущена в более старом (обычном) режиме перемещаемой ссылки на память или в страничном режиме. По мере разработки большего количества исполняемых форматов были добавлены новые константы путем увеличения смещения ветвления.
В исходном коде Sixth Edition загрузчика программ Unix функция exec () считывает исполняемый ( двоичный ) образ из файловой системы. Первые 8 байтов файла представляли собой заголовок, содержащий размеры программных (текстовых) и инициализированных (глобальных) областей данных. Кроме того, первое 16-битное слово заголовка сравнивалось с двумя константами, чтобы определить, содержит ли исполняемое изображение перемещаемые ссылки на память (обычно), недавно реализованное выгружаемое исполняемое изображение только для чтения или разделенные инструкции и выгружаемое изображение данных. Не было упоминания о двойной роли константы заголовка, но старший байт константы фактически был кодом операции для инструкции ветвления PDP-11 ( восьмеричное 000407 или шестнадцатеричное 0107). Добавление семи к счетчику программы показало, что если эта константа будет выполнена, она разветвит службу Unix exec () над восьмибайтовым заголовком исполняемого образа и запустит программу.
Поскольку в шестой и седьмой редакциях Unix использовался код подкачки, двойная роль константы заголовка была скрыта. То есть служба exec () считывает данные заголовка исполняемого файла ( метаданные ) в буфер пространства ядра, но считывает исполняемый образ в пространство пользователя, тем самым не используя функцию ветвления константы. Создание магических чисел было реализовано в компоновщике Unix и загрузчике, а ветвление магических чисел, вероятно, все еще использовалось в наборе автономных диагностических программ, которые поставлялись с Шестой и Седьмой редакциями. Таким образом, константа заголовка действительно создавала иллюзию и удовлетворяла критериям магии.
В седьмой версии Unix константа заголовка не тестировалась напрямую, а присваивалась переменной с меткой ux_mag и впоследствии называлась магическим числом. Вероятно, из-за своей уникальности термин « магическое число» стал обозначать тип исполняемого формата, затем расширился до обозначения типа файловой системы и снова расширился до обозначения любого типа файла.
Магические числа распространены в программах многих операционных систем. Магические числа реализуют строго типизированные данные и являются формой внутриполосной передачи сигналов управляющей программе, которая считывает тип (ы) данных во время выполнения программы. Многие файлы имеют такие константы, которые идентифицируют содержащиеся данные. Обнаружение таких констант в файлах - простой и эффективный способ различения многих форматов файлов и может дать дополнительную информацию во время выполнения.
CAFEBABE
. При сжатии с помощью Pack200 байты меняются на CAFED00D
.47
49
46
38
39
61
) или «GIF87a» ( 47
49
46
38
37
61
).FF
D8
и заканчиваются на FF
D9
. Файлы JPEG / JFIF содержат код ASCII для «JFIF» ( 4A
46
49
46
) в виде строки с завершающим нулем. Файлы JPEG / Exif содержат код ASCII для «Exif» ( 45
78
69
66
) также в виде строки с завершающим нулем, за которой следуют дополнительные метаданные о файле.\211
P
N
G
\r
\n
\032
\n
( 89
50
4E
47
0D
0A
1A
0A
). Эта подпись содержит различные символы новой строки, позволяющие обнаруживать необоснованные автоматические преобразования новой строки, такие как передача файла с использованием FTP с режимом передачи ASCII вместо двоичного режима. 4D
54
68
64
), а затем больше метаданных.23
21
), А затем путем к переводчику, если переводчик, вероятно, будет отличаться от того, из которого был вызван скрипт.7F
E
L
F
25
21
).25
50
44
46
).4D
5A
), инициалов дизайнера формата файла, Mark Zbikowski. Определение допускает необычный "ZM" ( 5A
4D
) также для dosZMXP, не-PE EXE.19
54
01
19
или в 01
19
54
зависимости от версии; оба представляют день рождения автора, Маршалла Кирка МакКьюзика.55
AA
4A
6F
79
21
) в качестве префикса.II
или MM
после 42 в виде двухбайтового целого числа с прямым или обратным порядком байтов. II
для Intel, которая использует порядок байтов с прямым порядком байтов, поэтому магическим числом является 49
49
2A
00
. MM
для Motorola, в которой используется порядок байтов с прямым порядком байтов, поэтому магическим числом является 4D
4D
00
2A
.FE
FF
для прямого и FF
FE
для обратного порядка байтов). А на Microsoft Windows, UTF-8 текстовые файлы часто начинаются с кодировкой UTF-8 того же характера, EF
BB
BF
.BC
(0x42, 0x43)IWAD
или PWAD
(для Doom ), WAD2
(для Quake ) и WAD3
(для Half-Life ).D0
CF
11
E0
, что визуально напоминает слово «DOCFILE0».50
4B
), инициалов Фила Каца, автора утилиты сжатия DOS PKZIP.37
7A
BC
AF
27
1C
.Утилита Unix file
может считывать и интерпретировать магические числа из файлов, а файл, который используется для анализа информации, называется магическим. Утилита Windows TrID имеет аналогичное назначение.
2A
.52
46
42
для «Remote Frame Buffer»), за которым следует номер версии протокола клиента.FF
53
4D
42
' или "\xFFSMB"
в начале запроса SMB.05
начала запроса (представляющего Microsoft DCE / RPC версии 5), за которым сразу следует 00
или 01
для дополнительной версии. В запросах MSRPC на основе UDP всегда стоит первый байт 04
.4D
45
4F
57
). Расширения отладки (используемые для подключения канала DCOM) предваряются байтовой последовательностью «MARB» ( 4D
41
52
42
).19
представляющее длину заголовка, за которым сразу следует фраза «Протокол BitTorrent» в позиции байта 1.E3
представляет клиента eDonkey, C5
представляет собой eMule и D4
представляет собой сжатый eMule.04
байты блока в цепочке блоков биткойнов содержат магическое число, которое служит идентификатором сети. Значение является константой 0xD9B4BEF9
, которая указывает основную сеть, в то время как константа 0xDAB5BFFA
указывает тестовую сеть.80
а ответ сервера SSLv3 на приветствие клиента начинается с 16
(хотя это может отличаться).0x63
0x82
0x53
0x63
», в начале раздела параметров пакета. Это значение входит во все типы пакетов DHCP.0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a
' или " PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n
". Предисловие разработано, чтобы избежать обработки кадров серверами и посредниками, которые поддерживают более ранние версии HTTP, но не 2.0.Магические числа распространены в функциях и интерфейсах API во многих операционных системах, включая DOS, Windows и NetWare :
0000
и 1234
решают, должна ли система подсчитывать память или нет при перезагрузке, тем самым выполняя холодную или горячую перезагрузку. Эти значения также используются диспетчерами памяти EMM386, перехватывающими запросы загрузки. BIOS также использует магические значения, 55 AA
чтобы определить, является ли диск загрузочным.Это список ограничений типов хранения данных:
Десятичная дробь | Шестигранник | Описание |
---|---|---|
18 446 744 073 709 551 615 | FFFF FFFF FFFF FFFF | Максимальное 64-битное значение без знака (2 64 - 1) |
9 223 372 036 854 775 807 | 7FFF FFFF FFFF FFFF | Максимальное 64-битное значение со знаком (2 63 - 1) |
4 294 967 295 | FFFF FFFF | Максимальное 32-битное значение без знака (2 32 - 1) |
2 147 483 647 | 7FFF FFFF | Максимальное 32-битное значение со знаком (2 31 - 1) |
65 535 | FFFF | Максимальное 16-битное значение без знака (2 16 - 1) |
32 767 | 7FFF | Максимальное 16-битное значение со знаком (2 15 - 1) |
255 | FF | Максимальное беззнаковое 8-битное значение (2 8 - 1) |
127 | 7F | Максимальное 8-битное значение со знаком (2 7 - 1) |
−128 | 80 | Минимальное 8-битное значение со знаком |
−32 768 | 8000 | Минимальное 16-битное значение со знаком |
-2 147 483 648 | 8000 0000 | Минимальное 32-битное значение со знаком |
-9 223 372 036 854 775 808 | 8000 0000 0000 0000 | Минимальное 64-битное значение со знаком |
Можно создать или изменить глобальные уникальные идентификаторы (GUID), чтобы они были запоминающимися, но это крайне не рекомендуется, поскольку это ставит под угрозу их силу в качестве почти уникальных идентификаторов. Спецификации для генерации GUID и UUID довольно сложны, что делает их практически уникальными при правильной реализации. Они должны создаваться только надежным программным средством.
Идентификационные номера продуктов Microsoft Windows для продуктов Microsoft Office иногда заканчиваются на 0000-0000-0000000FF1CE («ОФИС»), например { 90160000-008C-0000-0000-0000000FF1CE }, идентификатор продукта для «Office 16 нажми и работай. Компонент расширяемости ".
Java использует несколько идентификаторов GUID, начиная с CAFEEFAC
.
В таблице разделов GUID схемы разделов GPT загрузочные разделы BIOS используют специальный идентификатор GUID { 21686148-6449-6E6F-744E-656564454649 }, который не соответствует определению GUID; вместо этого он формируется с использованием кодов ASCII для строки « Hah! IdontNeedEFI » частично в порядке обратного порядка байтов.
Значения отладки Magic - это особые значения, записываемые в память во время выделения или освобождения, чтобы позже можно было определить, были ли они повреждены, и сделать это очевидным, когда используются значения, взятые из неинициализированной памяти. Память обычно просматривается в шестнадцатеричном формате, поэтому часто встречаются запоминающиеся повторяющиеся или шестнадцатеричные значения. Могут быть предпочтительны числовые нечетные значения, так что процессоры без байтовой адресации будут давать сбой при попытке использовать их в качестве указателей (которые должны попадать в четные адреса). Следует выбирать значения, которые не соответствуют вероятным адресам (программный код, статические данные, данные кучи или стек). Точно так же они могут быть выбраны так, чтобы они не были допустимыми кодами в наборе команд для данной архитектуры.
Поскольку очень маловероятно, хотя и возможно, что 32-битное целое число примет это конкретное значение, появление такого числа в отладчике или дампе памяти, скорее всего, указывает на ошибку, такую как переполнение буфера или неинициализированная переменная.
Известные и распространенные примеры включают:
Код | Описание |
---|---|
00008123 | Используется в MS Visual C ++. Для удаленных указателей устанавливается это значение, поэтому они вызывают исключение, когда используются после; это более узнаваемый псевдоним нулевого адреса. Он активируется с помощью параметра «Жизненный цикл разработки безопасности» (/ sdl). |
..FACADE | "Фасад", используется рядом ОСРВ. |
1BADB002 | «1 плохая загрузка», магический номер заголовка мультизагрузки |
8BADF00D | «Съел плохую еду». Указывает, что приложение Apple iOS было закрыто из-за тайм-аута сторожевого таймера. |
A5A5A5A5 | Используется во встроенной разработке, поскольку чередующийся битовый шаблон (1010 0101) создает легко распознаваемый шаблон на осциллографах и логических анализаторах. |
A5 | Используется во FreeBSD PHK malloc (3) для отладки, когда /etc/malloc.conf символически привязан к «-J» для инициализации всей вновь выделенной памяти, поскольку это значение не является указателем NULL или символом NUL ASCII. |
ABABABAB | Используется функцией отладки Microsoft HeapAlloc () для отметки защитных байтов «ничейной земли» после выделенной памяти кучи. |
ABADBABE | «Плохая малышка», используется Apple как магическое число «Boot Zero Block». |
ABBABABE | " ABBA babe", используемый кучей памяти Driver Parallel Lines. |
ABADCAFE | «Плохое кафе», используется для инициализации всей нераспределенной памяти (Mungwall, AmigaOS ) |
B16B00B5 | «Big Boobs», ранее требуется Microsoft «S Hyper-V гипервизора, который будет использоваться в качестве гостей Linux верхней половины своего„гостя ид“ |
BAADF00D | "Плохая еда", используется функцией отладки Microsoft HeapAlloc () для отметки неинициализированной выделенной памяти кучи. |
BAAAAAAD | "Baaaaaad", означает, что журнал Apple iOS представляет собой стек всей системы, а не отчет о сбое. |
BAD22222 | "Плохо слишком часто ". Указывает, что приложение Apple iOS VoIP было закрыто, потому что оно возобновлялось слишком часто. |
BADBADBADBAD | «Плохо, плохо, плохо, плохо», большие системы Берроуза «неинициализированная» память (48-битные слова) |
BADC0FFEE0DDF00D | «Плохой кофе, странная еда», используется в 64-битных системах IBM RS / 6000 для обозначения неинициализированных регистров ЦП. |
BADDCAFE | "Bad кафе", на Sun Microsystems ' Solaris, отмечает неинициализированную память ядра (KMEM_UNINITIALIZED_PATTERN) |
BBADBEEF | «Плохая говядина», используется в WebKit |
BEEFCACE | "Говяжий пирог", используемый Microsoft.NET в качестве магического числа в файлах ресурсов. |
C00010FF | «Остыть», означает, что приложение Apple iOS было отключено операционной системой в ответ на тепловое событие. |
CAFEBABE | "Cafe babe", используется Java для файлов классов. |
CAFED00D | "Cafe dude", используется Java для сжатия pack200. |
CAFEFEED | «Кафе кормить», Используется Sun Microsystems ' Solaris отладки ядра для марки kmemfree () память |
CCCCCCCC | Используется библиотекой времени выполнения отладки C ++ от Microsoft и многими средами DOS для отметки неинициализированной памяти стека. CC напоминает код операции прерывания от точки останова отладки INT 3 на процессорах x86. |
CDCDCDCD | Используется функцией Microsoft C / C ++ debug malloc () для отметки неинициализированной памяти кучи, обычно возвращаемой из HeapAlloc () |
0D15EA5E | "Zero Disease", используется как флаг для обозначения регулярной загрузки на консолях Nintendo GameCube и Wii. |
DDDDDDDD | Используется функцией SmartHeap MicroQuill и функцией debug free () Microsoft C / C ++ для отметки освобожденной памяти кучи. |
DEAD10CC | «Мертвая блокировка». Указывает, что приложение Apple iOS было прекращено, потому что оно удерживало системный ресурс во время работы в фоновом режиме. |
DEADBABE | «Мертвый младенец», использован в начале Silicon Graphics ' IRIX арена файлов |
DEADBEEF | «Мертвая говядина», широко используемая в системах IBM, таких как RS / 6000, также используется в классических операционных системах Mac OS, OPENSTEP Enterprise и Commodore Amiga. В компании Sun Microsystems ' Solaris, отмечает освободила памяти ядра (KMEM_FREE_PATTERN) |
DEADCAFE | "Мертвое кафе", используется Microsoft.NET как номер ошибки в библиотеках DLL. |
DEADC0DE | «Мертвый код», используется в качестве маркера в прошивке OpenWRT для обозначения начала создаваемой файловой системы jffs2 в конце статической прошивки. |
DEADFA11 | «Мертвая ошибка». Указывает, что приложение Apple iOS было принудительно закрыто пользователем. |
DEADF00D | «Мертвая еда», используется Mungwall на Commodore Amiga для обозначения выделенной, но неинициализированной памяти. |
DEFEC8ED | "Defecated", используется для дампов ядра OpenSolaris. |
DEADDEAD | «Dead Dead» означает, что пользователь намеренно инициировал аварийный дамп либо с помощью отладчика ядра, либо с клавиатуры. |
D00D2BAD | "Dude, Too Bad", используется Safari, дает сбой на macOS Big Sur. |
EBEBEBEB | Из SmartHeap от MicroQuill |
FADEDEAD | "Fade dead", идет в конце, чтобы идентифицировать каждый сценарий AppleScript. |
FDFDFDFD | Используется функцией Microsoft C / C ++ debug malloc () для отметки защитных байтов «ничейной земли» до и после выделенной памяти кучи, а также некоторыми функциями отладки Secure C-Runtime, реализованными Microsoft (например, strncat_s) |
FEE1DEAD | «Feel мертвым», Используется Linux перезагрузки () системный вызов |
FEEDFACE | "Подача лицо", посещение в PowerPC Mach-O бинарных файлов на Apple Inc. «s MacOS платформы. В компании Sun Microsystems ' Solaris, отмечает красная зона (KMEM_REDZONE_PATTERN) Используется VLC - плеер и некоторые IP - камеры в RTP / RTCP протоколе, VLC игрок посылает четыре байта в порядке байт системы. Некоторые IP-камеры ожидают, что плеер отправит это магическое число, и не запускают поток, если он не получен. |
FEEEFEEE | «Комиссионный сбор». Используется отладкой Microsoft HeapFree () для отметки освобожденной памяти кучи. Для некоторых близлежащих значений внутренней бухгалтерской отчетности также может быть установлено старшее слово FEEE. |
Большинство из них имеют длину 32 бита - размер слова большинства компьютеров с 32-битной архитектурой.
Преобладание этих ценностей в технологиях Microsoft неслучайно; они подробно обсуждаются в книге Стива Магуайра « Написание твердого кода» от Microsoft Press. Он дает множество критериев для этих ценностей, таких как:
Так как они часто использовались для обозначения областей памяти, которые были по существу пустыми, некоторые из этих терминов стали использоваться во фразах, означающих «пропал, прерван, стерто из памяти»; например, «Ваша программа DEADBEEF».