Давайте поговорим немного о Hex.

В этом посте я объясняю данные, поскольку они действительно существуют в наших компьютерах. Если вы когда-нибудь задумывались, как последовательность из 1 и 0 приводит к получению значимой информации, эта статья для вас.

Биты и байты

Все данные в компьютере представлены в виде последовательности нулей и единиц. В зависимости от того, где находятся данные - RAM, SSD, HDD, DVD и т. Д. - единицы и нули кодируются по-разному физически, но концептуально это два различных состояния - и это все, что есть на самом деле.

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

Предположим, у вас есть 40 бит данных, поэтому 5 байтов:

01001000 01100101 01101100 01101100 01101111

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

Кстати, в конце статьи вы сможете вернуться к 40 битам, указанным выше, и понять, что они означают. Когда доберетесь туда, попробуйте вернуться и посмотреть на это. Вы разберетесь. Я обещаю.

Почему у байта 8 бит, а не 10?

Смесь исторических и практических причин.

Я постараюсь намекнуть на основные практические проблемы. Давайте сделаем шаг назад на секунду: для нас умножение или деление на степень 10 является тривиальным делом, просто добавляя нули или сдвигая десятичную точку, верно?

3.1415 ✕ 100 = 314.15

Это верно для нашей десятичной системы - системы счисления, основанной на степени 10.

Компьютеры внутренне выполняют двоичную арифметику. Двоичная арифметика основана на степенях двойки. В двоичной арифметике одинаково удобны степени двойки, такие как 8 = 2³.

Давайте посмотрим на пример из двоичной арифметики:

13 ✕ 8 = 104 соответствует 00001101 ✕ 1000 = 01101000

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

В итоге: если размер единиц данных является степенью двойки, например, 8 = 2³, многие внутренние вычисления, которые необходимо выполнить компьютеру, будут намного проще, чем они были бы в противном случае.

Сколько байтов в килобайте?

Хороший вопрос. До 1998 года не существовало официальной стандартизации в отношении килобайт, мегабайт, гигабайт и т. Д. Тем не менее, эти единицы широко использовались как техническими специалистами, так и потребителями. Вы купили жесткий диск, размер его был указан в гигабайтах.

Технологи считали 2¹⁰ = 1024 байта на килобайт, 1024 килобайта на мегабайт, 1024 мегабайта на гигабайт и так далее. Как мы узнали, степень двойки - это практичная вещь, которую можно использовать при работе с памятью компьютера.

Известно, что у маркетологов, продающих жесткие диски, возникла гениальная идея, что без официальной стандартизации они могут просто заявить, что их единицы основаны на 1000, и, следовательно, их гигабайт равен 1000³ = 1 000 000 000 байт - вместо 1024³ = 1 073 741 824, поэтому они могли разыграть тебя в космосе. Чем больше драйв, тем больше разница.

Вы купили свой жесткий диск на 500 ГБ и все время задавались вопросом, почему ваш компьютер продолжает утверждать, что его размер составляет всего 465,66 ГБ.

Что ж, стандартизация в конечном итоге произошла в 1998 году. К сожалению, корпоративная жадность стала официальным стандартом, и исходные единицы, основанные на 2¹⁰ = 1024, стали единицами би: кибибайты, мебибайты, гибибайты и т. Д. Что еще хуже, обычные короткие формы, КБ, МБ, ГБ, впитались и т. д. Исходные единицы base-2 теперь - KiB, MiB и GiB.

За пределами академических кругов большинство технических специалистов все еще понимают килобайт как 1024 байта. Мир программного обеспечения раскололся, и некоторые компании начали принимать этот «стандарт», некоторые - нет. Некоторые позволяют выбирать.

Но я отвлекся.

Анатомия байта

Давайте посмотрим на пример байтового значения: 01101101

Прочтите значение вслух и повторите его по памяти. Нелегко, правда?

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

Вместо битового шаблона мы можем начать использовать символы. Наше байтовое значение 01101101 становится 6D.

Это называется шестнадцатеричным представлением - сокращенно шестнадцатеричным - потому что существует 16 различных символов. Кроме того, поскольку существует возможность неоднозначности с десятичными числами, шестнадцатеричные значения часто имеют префикс 0x, чтобы устранить эту неоднозначность. Итак, мы смотрим на 0x6D.

Это еще не интерпретация, это просто более компактный способ записать - и сказать - значение.

Интерпретация двоичных данных

То, что означают единицы и нули, полностью зависит от контекста.

«Так каково информационное содержание 0x6D?»

"Это узор из единиц и нулей"

«Да, но что это значит?»

"Это только нули и единицы"

"Я понимаю"

Если бы вы интерпретировали 0x6D как символ ASCII, это было бы m. Если бы вы интерпретировали это как число с дополнением до двух, это было бы 109. Если бы вы интерпретировали его как число с фиксированной запятой с 3-мя дробными знаками, это было бы 13.625.

Когда вам предоставляется фрагмент двоичных данных, вам обычно нужно дать контекст, чтобы понять его. Для текстовых файлов это кодировка, которая в наши дни в основном представляет собой UTF-8 - кодировку, совместимую с ASCII для текстовых символов. Для других типов файлов, например файла PNG, вам необходимо найти значение данных в соответствующей спецификации формата файла.

Двоичные целые числа

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

Из спецификации формата файла PNG:

«Первые восемь байтов потока данных PNG всегда содержат следующие (десятичные) значения:

137 80 78 71 13 10 26 10

Итак ... какова последовательность битов для этих десятичных значений? Давайте пока будем придерживаться нашего значения 0x6D. Мы узнаем. Шестнадцатеричное значение 0x6D - это число 109, но как я могу это узнать?

Мы привыкли к десятичной системе счисления. Но выбор 10 в качестве базы и 0–9 в качестве цифр совершенно произвольный.

Мы просто животные с 10 пальцами на руках, и это делает количество привычным и механически удобным при подсчете - скажем, поголовье или мешки риса. Число 10 не является особенным по своей сути, оно просто практично для нас, людей.

Десятичная система

Когда мы записываем числа, мы записываем цифру в диапазоне 0-9 для каждой степени нашей базы 10, начиная с 10⁰ справа. Мы добавляем цифры слева для дополнительных степеней 10, если они нам нужны для выражения нашего числа.

Восьмеричная система

Мы могли бы использовать меньшую базу 8 вместо цифр 0–7. Это называется восьмеричной системой. Это не полностью выдуманный пример. Он действительно используется. Возможно, вы видели это в контексте прав доступа к файлам в системах Linux. Точно так же, как шестнадцатеричные числа часто имеют префикс 0x, чтобы устранить двусмысленность, восьмеричные числа часто имеют префикс 0.

Шестнадцатеричная система

Итак, мы перешли с 10 на базу 8. Мы также можем подняться, скажем, на базу 16. Однако у нас будут проблемы с цифрами.

Нам нужны цифры для 0–15 и последние 9, мы не придерживаемся установленных правил. Давайте использовать шестнадцатеричные цифры: A=10, B=11, C=12, D=13, E=14, F=15

Двоичная система

Выбор основания является совершенно произвольным, если у нас есть согласованные цифры. Давайте сделаем полный минимализм и воспользуемся базой 2 с цифрами 0–1.

Целочисленная сводка

Теперь вы видите, как 01101101, 0x6D и 109 are все разные обозначения для одного и того же целого числа. И теперь должно быть понятно, как, глядя на такую ​​таблицу ASCII, они индексируются с использованием различных форматов. Это просто любезность, так что вы можете найти персонажа, используя индекс в любой системе, которая у вас есть под рукой.

Двоичный текст

Откройте редактор текстового редактирования, создайте новый файл, вставьте в него «Hello World» и сохраните его как простой текстовый файл.

Теперь получите шестнадцатеричный редактор. Шестнадцатеричный редактор - это просто редактор файлов, который не интерпретирует содержимое файла за вас - он просто показывает необработанное двоичное содержимое. Подойдет любой базовый бесплатный шестнадцатеричный редактор. Вы также можете использовать шестнадцатеричный онлайн-редактор.

Откройте текстовый файл в шестнадцатеричном редакторе. Он покажет вам двоичное содержимое файла. Это должно выглядеть примерно так.

Шестнадцатеричный редактор обычно показывает вам три столбца: смещение от начала файла (обычно в шестнадцатеричном формате), двоичное содержимое файла (также в шестнадцатеричном формате), а третий столбец показывает байты файла, интерпретированные как символы ASCII.

Если содержимое вашего файла содержит несколько дополнительных байтов в начале, вероятно, ваш текстовый редактор сохранил BOM в вашем файле. Не беспокойся об этом.

Помните наши 40 бит из прошлого? Теперь вы знаете все, что вам нужно, чтобы понять, что это говорит.

01001000 01100101 01101100 01101100 01101111

Углубляясь

У нас есть основы. Каждая из следующих тем заслуживает отдельной статьи. Но нам уже не хватает места, времени и внимания читателя, поэтому я указываю вам на ресурсы, которые можно будет просмотреть позже.

Я знаю, что у вас еще есть вопросы! 🤓

Правильные целые числа

До сих пор мы говорили только о положительных целых числах, ограничиваясь одним байтом за раз. Но…

«Как насчет кодирования целых чисел больше 255? В байте недостаточно битов для хранения более высоких значений. А как насчет отрицательных чисел? »

Хорошие вопросы. Вы используете последовательные байты фиксированной длины - обычно 2 байта, 4 байта и 8 байтов - и это расширяет имеющиеся у вас степени двойки. Для целых чисел со знаком используется кодировка дополнение до двух.

Большинство калькуляторов, не относящихся к игрушечным, имеют нормальный, научный и программный режим просмотра. Включите на своем калькуляторе «взгляд программиста», когда будете изучать этот материал.

Когда вы начинаете использовать более одного байта для представления значения, порядок байтов становится важным, особенно при чтении байтов из файлов или сети, так что имейте это в виду.

Дробные числа

До сих пор мы говорили только о целых числах. Что о:

π=3.1415926535…

Существует стандартизованное представление дробных чисел с плавающей запятой с аппаратной поддержкой. Наиболее часто используемые версии - это 4-байтовая одинарная точность, часто называемая float, и 8-байтовая версия, которая обычно называется double.

Общая идея такова:

Знак сохраняется в крайнем левом бите. 0 означает положительное число, 1 означает отрицательное число. Число в нашем примере положительное.

Заштрихованное красным дробное число равно 1 плюс сумма выбранных отрицательных степеней двойки, то есть половинки, четверти, восьмерки и т. Д.… В приведенном выше примере у нас установлен бит только в позиции четвертей. Итак, дробное число 1.25

Обратите внимание, что дробное число всегда находится в диапазоне от 1.0 включительно до 2.0 исключительного.

На следующем этапе вы вычисляете показатель степени, заданный битами, заштрихованными зеленым цветом. Наша экспонента 124. Стандарт требует умножать дробное число на 2^(exp-127), поэтому в нашем случае мы умножаем на 2^-3 = 1/8.

Наконец, число, закодированное нашим битовым шаблоном, выглядит так:

1.25 × 1/8 = 0,15625

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

О, а что касается π, попробуйте интерпретировать этот паттерн:

0 10000000 10010010000111111011011

Вам также может быть интересно, насколько точное приближение к десятичным дробям теперь, когда мы используем половинные вместо десятых. Многие делают, даже те, кто делает Excel.

Заключение

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

Чтобы проверить свое понимание, попробуйте взглянуть на спецификацию формата файла формы и посмотреть, есть ли в этом смысл.