Перевод из восьмеричной в десятичную
Быстрый перевод чисел из системы счисления по основанию 8 в обычную десятичную.
Если ввести parseInt("010") в консоль старых версий JavaScript без указания второго аргумента, вернется 8 вместо ожидаемой десятки. Причина проста: раньше ведущий ноль обозначал восьмеричное число, что годами ломало логику скриптов до изменения стандартов.
Основание 8 и позиционный принцип
В восьмеричной записи позиция каждой цифры соответствует степени 8, а не степени 10. Допустимый диапазон цифр здесь строго от 0 до 7 — значений 8 или 9 в восьмеричном числе не бывает в принципе. Возьмем восьмеричное значение 57: цифра 5 находится в разряде восьмерок, а 7 — в разряде единиц.
Итоговый перевод выглядит так: (5 × 8) + 7 = 47. Точно такое же значение обозначают 2F в шестнадцатеричном виде и 101111 в двоичной системе счисления. Это три разные формы записи одной и той же величины, о чем полезно помнить при анализе непривычных форматов данных.
История ошибки с ведущим нулем
В языке C числовой литерал, начинающийся с символа 0, всегда интерпретировался компилятором как восьмеричный: запись 010 в коде на C означает 8, а не десять. Долгое время JavaScript негласно копировал это поведение, пока его не формализовали, а затем окончательно не признали устаревшим.
Проблема регулярно возникала при форматировании данных с ведущими нулями — например, при обработке дат, почтовых индексов или артикулов товаров. Передача такой строки в парсер без явного указания основания 10 приводила к неожиданным ошибкам. Стандарт ECMAScript 5 закрепил за parseInt десятичную систему по умолчанию, но старое поведение все еще встречается в легаси-проектах.
Шаги ручного перевода восьмеричного числа
- Выпиши каждую цифру восьмеричного числа вместе с номером ее позиции справа налево, начиная с 0.
- Умножь каждую отдельную цифру на 8, возведенную в степень ее позиции.
- Сложи полученные промежуточные произведения между собой.
- Убедись, что исходное число не содержало цифр 8 или 9, иначе оно изначально не являлось корректным восьмеричным значением.
Сферы практического применения восьмеричных литералов
- Права доступа Unix — Значения команд chmod и umask традиционно задаются в восьмеричном формате, поэтому их принято записывать с ведущим нулем или явным префиксом системы счисления.
- Исходный код на C и C++ — Ведущий ноль в целочисленном литерале по-прежнему обозначает основание 8, сохраняя совместимость с самыми первыми версиями стандарта.
- Современные префиксы языков — Актуальные версии JavaScript, Python и других языков требуют явный префикс
0oдля восьмеричных чисел, что исключает двусмысленность.
Вопросы о переводе из восьмеричной системы
Почему в восьмеричной системе допустимы только цифры от 0 до 7?
Восьмеричная система использует основание 8, поэтому один разряд может кодировать лишь восемь вариантов значений. Появление цифры 8 или 9 делает запись невалидной, точно так же как цифра 2 недопустима в двоичном формате.
Используется ли восьмеричная запись где-то кроме прав Unix?
В современных проектах редко. Помимо битов доступа к файлам, она иногда встречается в старых прошивках встраиваемых систем, архивных форматах данных и коде на языках семейства C.
В чем именно заключалась уязвимость функции parseInt?
Устаревшие движки JavaScript воспринимали строковые значения с первым символом 0 как восьмеричные при вызове parseInt без второго аргумента. Строка «010» тихо превращалась в 8 вместо десяти, ломая математические расчеты.
Чем этот расчет отличается от расшифровки chmod?
Математическая основа абсолютно та же самая, поскольку десятичное представление — это лишь один из способов интерпретации цифр. В chmod те же разряды рассматриваются как битовые флаги прав доступа к объектам файловой системы.
Поддерживает ли современный JavaScript восьмеричный формат?
Да, поддержка осталась, но требует обязательного префикса 0o, как в примере 0o57. Неявное определение через ведущий ноль объявлено устаревшим и заблокировано в строгом режиме.