Конвертация чисел в hex-строку в Python: эффективные решения и альтернативы

Раздел: Алгоритмы -> Преобразование чисел

Основные подходы к переводу чисел в hex

Встроенная функция hex()

Как быстро перевести целое число в шестнадцатеричную строку с префиксом '0x'?

number = 255
hex_string = hex(number)
print(hex_string)  # '0xff'

шестнадцатеричное число python (преобразование числа в шестнадцатеричную систему в python)

Функция hex() принимает целое число и возвращает строку, начинающуюся с '0x', за которой следуют цифры в нижнем регистре. Это самый простой и эффективный способ, рекомендуемый для большинства задач.

  1. Ошибка TypeError: передача нецелого числа (например, float) вызывает исключение. Решение: предварительно преобразовать число к int, либо использовать другой метод (например, через struct для float).
  2. Отрицательные числа: hex(-1) вернет '-0x1'. Если требуется беззнаковое представление, можно использовать побитовую операцию с маской.
  3. Отсутствие контроля формата: нельзя убрать префикс или изменить регистр без дополнительных манипуляций. Для этого лучше подходят функции форматирования.

Форматирование строк с помощью format()

Как получить шестнадцатеричное представление без префикса или с заглавными буквами?

number = 255
# Без префикса, нижний регистр
hex_lower = format(number, 'x')
print(hex_lower)  # 'ff'

# С префиксом 0x, нижний регистр
hex_with_prefix = format(number, '#x')
print(hex_with_prefix)  # '0xff'

# Заглавные буквы
hex_upper = format(number, 'X')
print(hex_upper)  # 'FF'

# Фиксированная ширина с дополнением нулями
hex_padded = format(number, '04X')
print(hex_padded)  # '00FF'

Функция format() дает гибкий контроль над отображением. Спецификаторы 'x' (нижний регистр) и 'X' (верхний) позволяют управлять регистром, а символ '#' добавляет префикс '0x' или '0X'. Дополнительно можно задать минимальную ширину поля (например, '04X').

Возможные проблемы: если число отрицательное, префикс '#' не добавляет минус, минус выводится отдельно. Для больших чисел ширина может быть превышена, тогда дополнение не применяется.

Использование f-строк

Как компактно вставить шестнадцатеричное представление в строку?

number = 255
# Аналогично format() внутри f-строки
print(f"Число в hex: {number:#x}")  # 'Число в hex: 0xff'
print(f"Без префикса: {number:x}")   # 'Без префикса: ff'
print(f"Заглавные: {number:X}")     # 'Заглавные: FF'
print(f"С дополнением: {number:04X}") # 'С дополнением: 00FF'

f-строки с синтаксисом {переменная:спецификатор} работают так же, как format(), но встроены прямо в строковый литерал. Это удобно для интерполяции.

Ошибки те же, что и у format(): передача нечислового значения вызовет TypeError.

Ручная реализация алгоритма деления на 16

Как понять внутренний механизм преобразования чисел в шестнадцатеричную систему?

def to_hex(n):
    if n == 0:
        return "0"
    digits = "0123456789abcdef"
    result = ""
    while n > 0:
        remainder = n % 16
        result = digits[remainder] + result
        n //= 16
    return result

print(to_hex(255))   # 'ff'
print(to_hex(16))    # '10'
print(to_hex(0))     # '0'

Алгоритм заключается в многократном делении числа на 16 с записью остатков в обратном порядке. Этот метод неэффективен для продакшена, но полезен для обучения.

Проблемы: не обрабатывает отрицательные числа и дробные. Для отрицательных нужно учитывать знак или использовать дополнительный код. Не добавляет префикс.

Преобразование с помощью метода строки .format()

Как использовать строковый метод format() вместо глобальной функции?

number = 255
hex_string = "{:x}".format(number)
print(hex_string)  # 'ff'
# с префиксом
hex_string = "{:#x}".format(number)
print(hex_string)  # '0xff'

Метод str.format() является эквивалентом глобальной функции format(), но вызывается на строке-шаблоне. Результат идентичен.

Разницы с format() нет, но может быть удобнее при конструировании сложных шаблонов.

Расширенные примеры и нестандартные случаи

Преобразование списка целых чисел в шестнадцатеричные строки

Пример
numbers = [0, 16, 255, 1024, 65535]
hex_list = [hex(n) for n in numbers]
print(hex_list)
# ['0x0', '0x10', '0xff', '0x400', '0xffff']
['0x0', '0x10', '0xff', '0x400', '0xffff']

Применение: вывод дампов памяти, кодирование цветов, хеши.

Обратное преобразование hex-строки обратно в число

Пример
hex_str = "0xff"
number = int(hex_str, 16)
print(number)  # 255

# без префикса
hex_str2 = "FF"
number2 = int(hex_str2, 16)
print(number2)  # 255
255
255

Функция int() с указанием основания (16) корректно обрабатывает как строки с префиксом '0x', так и без него.

Получение беззнакового представления для отрицательных чисел

Пример
def to_hex_unsigned(n, bits=32):
    # битовая маска
    mask = (1 << bits) - 1
    # приводим к беззнаковому виду
    unsigned = n & mask
    return f"{unsigned:#0{bits//4+2}x}"

print(to_hex_unsigned(-1, 32))   # 0xffffffff
print(to_hex_unsigned(-255, 16)) # 0xff01
0xffffffff
0xff01

Полезно при работе с сетевыми протоколами, низкоуровневыми данными.

Преобразование числа с плавающей точкой в hex (IEEE 754)

Пример
import struct

def float_to_hex(f):
    # упаковываем в 8 байт (double) или 4 байта (float)
    packed = struct.pack('>d', f)  # big-endian double
    return packed.hex()

print(float_to_hex(3.141592653589793))
# '400921fb54442d18'
400921fb54442d18

Метод через struct.pack дает точное шестнадцатеричное представление числа с плавающей точкой по стандарту IEEE 754.

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

Пример
r, g, b = 255, 128, 64
hex_color = f"#{r:02X}{g:02X}{b:02X}"
print(hex_color)  # #FF8040
#FF8040

Часто используется в веб-дизайне.

Преобразование байтовой строки в hex с помощью bytes.hex()

Пример
data = b"Hello"
hex_str = data.hex()
print(hex_str)  # 48656c6c6f

# метод bytearray
ba = bytearray([0, 255, 16])
print(ba.hex())  # 00ff10
48656c6c6f
00ff10

Методы bytes.hex() и bytearray.hex() возвращают шестнадцатеричное представление последовательности байтов без разделителей.

Генерация шестнадцатеричных чисел с произвольным префиксом

Пример
number = 255
# можно использовать replace после hex()
no_prefix = hex(number).replace('0x', '')
print(no_prefix)  # ff
# или добавить свой префикс
custom = 'h' + no_prefix
print(custom)  # hff
ff
hff

Иногда требуется нестандартный префикс (например, 'h' в ассемблере).

Работа с очень большими числами

Пример
big = 2**256 - 1
hex_big = hex(big)
print(len(hex_big) - 2)  # количество шестнадцатеричных цифр (64)
print(hex_big[:20] + '...')
# '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
64
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

hex() корректно работает с числами произвольной величины.

Обработка ошибок при вводе

Пример
def safe_hex(value):
    try:
        return hex(int(value))
    except (ValueError, TypeError):
        return None

print(safe_hex("123abc"))  # None (не число)
print(safe_hex([1,2]))    # None
None
None

Важно обрабатывать исключения, если источник данных ненадёжен.

Преобразование числа в шестнадцатеричную систему в Python - comments

En
шестнадцатеричное число python (python)