Преобразование в шестнадцатеричную строку

Преобразование в шестнадцатеричную строку

При отладке программ, которые работают с бинарными данными, часто нужно вывести содержимое строки на экран, причём желательно в виде шестнадцатеричной строки.

Для этого можно использовать следующую небольшую функцию hex.

local function hex(s)
  return s:gsub(".", function(c)
    return ("%02x "):format(c:byte())
  end):sub(1, -2)
end

print(hex("\x01\x23\x45\x67\x89\xab\xcd\xef"))
--> 01 23 45 67 89 ab cd ef

Чтобы понять, как оно работает, нужно понимать, что для всех строк установлена метатаблица с полем __index, ссылающееся на string. Таким образом, для строки s запись s.sub(s, 1, 2) эквивалентна string.sub(s, 1, 2).

Так как первым аргументом метода строки передаётся сама строка, то можно сократить s.sub(s, 1, 2) до s:sub(1, 2).

Строковые литералы (строк, записанных прямо в коде, вроде "hey") также являются строками, поэтому у них также можно вызвать функции string. Однако напрямую индексировать литерал (в смысле, писать "test":sub(1, 2)) нельзя — это будет синтаксической ошибкой. Литерал нужно обернуть в скобки: ("test"):sub(1, 2) — эквивалентно string.sub("test", 1, 2), но короче.

Мы используем функцию string.gsub, передав шаблон "." (любой символ) и функцию. Функция будет вызываться для каждого символа и менять его на то, что она вернёт.

С помощью string.byte (c:byte()) мы получаем числовое значение байта. Затем передаём его в string.format с форматом "%02x ". %x конвертирует число в шестнадцатеричное, %02x также дополняет число слева нулямм до тех пор, пока длина его не будет равна двум (число 14 превращает в 0e, например). После каждого символа добавляем пробел.

Наконец, убираем в конце лишний пробел после последнего символа с помощью string.sub и возвращаем полученную строку.

Подробнее

results for ""

    No results matching ""