
Коли конвертація hex у текст іде не так: помилки кодування, що перетворюють байти на мотлох
Опубліковано 24 лип. 2026 р.
Здається, що конвертація hex у текст має бути безвідмовною: кожна пара шістнадцяткових цифр — один байт, зіставляєш байт із символом — готово. На практиці вона постійно ламається, і майже ніколи через зламаний конвертер — вона ламається тому, що hex — це лише спосіб запису байтів, а байтам потрібне узгоджене кодування, перш ніж вони взагалі означатимуть якийсь конкретний символ. Ось що насправді йде не так, коли вивід спотворений.
Причина 1: припущено неправильне кодування символів
Найпоширеніша причина. Байти в hex були закодовані як UTF-8 (де багато реальних символів займають 2–4 байти), а конвертер декодує байт за байтом, ніби це Latin-1 чи чистий ASCII (де кожен байт — рівно один символ). Результат: літери з діакритикою, фігурні лапки, довгі тире чи будь-які неанглійські символи перетворюються на два-три спотворені знаки замість одного правильного.
Виправлення завжди одне — декодувати тим самим кодуванням, яким байти були записані спочатку. Якщо ви не знаєте яким, то UTF-8 — правильний вибір за замовчуванням для всього сучасного (веб-контент, JSON, більшість API); Latin-1/Windows-1252 здебільшого трапляється лише у старих текстових файлах із Windows або в застарілих заголовках електронної пошти.
Причина 2: розбіжності порядку байтів (endianness)
Це стосується саме багатобайтових числових значень (не тексту), але в інструментах hex-у-текст, що обробляють змішані бінарно-текстові дані, трапляється достатньо часто, щоб про це сказати. 00 01, прочитане як big-endian, — це 1; ті самі два байти в little-endian — це 256. Якщо hex-рядок містить числовий префікс довжини або бінарне поле, вбудоване в загалом текстові дані, читання його з неправильним порядком байтів не просто спотворює число — воно зсуває кожну байтову позицію після нього, бо інструмент тепер вважає, що текст починається з неправильного зміщення.
Причина 3: помилки групування нібблів
Hex завжди має йти парами — дві шістнадцяткові цифри складають один байт. Непарна кількість hex-символів (одна зайва цифра, копіювання, що загубило символ, або початковий 0x, який не прибрали перед парсингом) зсуває кожну наступну пару на один ніббл. Кожен байт після помилки декодується в зовсім інший, не пов’язаний символ — вивід не «трохи неправильний», він повністю перемішаний від цієї точки й далі. І це насправді корисна діагностика: мотлох, що починається чисто й псується десь посередині рядка, вказує на помилку групування саме в тій позиції, а не на проблему з кодуванням (яка псує рівномірніше по всьому тексту).
Причина 4: невидимі та недруковані байти
Не кожен байт відповідає видимому символу. Керівні символи (0x00–0x1F), byte-order-mark (EF BB BF в UTF-8) і різні символи форматування Unicode декодуються «успішно», але відображаються як ніщо, квадратик або знак питання залежно від шрифту — що може виглядати ідентично до збою декодування, хоча сама конвертація була цілком правильною. Якщо довжина виводу виглядає правильно, але в тексті ніби бракує символів, перевірте наявність керівних байтів, перш ніж вважати логіку декодування зламаною.
Швидкий спосіб визначити, з чим саме ви маєте справу
- Переконайтеся, що hex-рядок має парну кількість символів — якщо ні, це причина 3, спочатку виправте вхідні дані.
- Спробуйте декодувати спершу як UTF-8, потім як Latin-1, і порівняйте — якщо одне дає чистий текст, а інше ні, це була причина 1.
- Якщо вивід рівномірно спотворений від найпершого символу, підозрюйте кодування (причина 1); якщо він починається чисто й псується посередині — підозрюйте помилку групування (причина 3) в тій позиції.
- Якщо довжина відповідає очікуванням, але окремі символи відсутні чи показуються квадратиками, перевірте керівні/форматувальні байти (причина 4), а не перевіряйте кодування ще раз.
Сама конвертація hex у текст — це один рядок коду будь-якою мовою; справжня робота з налагодження майже завжди полягає у з’ясуванні, яке з цих чотирьох припущень мовчки виявилося хибним, а не в логіці конвертації.