CodeKitHub
Kai hex į tekstą konvertuojasi ne taip: kodavimo klaidos, paverčiančios baitus šiukšlėmis

Kai hex į tekstą konvertuojasi ne taip: kodavimo klaidos, paverčiančios baitus šiukšlėmis

Paskelbta 2026-07-24

Atrodo, kad hex konvertavimas į tekstą turėtų būti patikimas kaip laikrodis: kiekviena hex skaitmenų pora — vienas baitas, baitą atvaizduoji į simbolį, ir baigta. Praktikoje tai nuolat nepavyksta, ir beveik niekada ne dėl to, kad konvertuoklis sugedęs — nepavyksta todėl, kad hex tėra būdas užrašyti baitus, o baitams reikia sutarto kodavimo, kad jie apskritai reikštų kokį nors konkretų simbolį. Štai kas iš tiesų vyksta, kai rezultatas iškraipytas.

1 priežastis: pritaikytas neteisingas simbolių kodavimas

Pati dažniausia priežastis. Hex baitai buvo užkoduoti kaip UTF-8 (kur daugelis realių simbolių užima 2–4 baitus), o konvertuoklis dekoduoja baitą po baito, tarsi tai būtų Latin-1 ar grynas ASCII (kur kiekvienas baitas yra lygiai vienas simbolis). Rezultatas: raidės su diakritikais, riestinės kabutės, ilgi brūkšniai ar bet kokie ne angliški simboliai virsta dviem ar trimis iškraipytais ženklais vietoj vieno teisingo.

Sprendimas visada tas pats — dekoduoti tuo pačiu kodavimu, kuriuo baitai buvo užrašyti; jei nežinote kuriuo, UTF-8 yra teisingas numatytasis pasirinkimas viskam, kas modernu (žiniatinklio turinys, JSON, dauguma API); Latin-1/Windows-1252 dažniausiai pasitaiko tik senesniuose iš Windows kilusiuose tekstiniuose failuose ar pasenusiose el. laiškų antraštėse.

2 priežastis: baitų tvarkos (endianness) neatitikimai

Ši priežastis liečia būtent daugiabaites skaitines reikšmes (ne tekstą), tačiau hex-į-tekstą įrankiuose, dirbančiuose su mišriais dvejetainiais/tekstiniais duomenimis, ji pasitaiko pakankamai dažnai, kad ją verta įvardyti. 00 01, perskaityta big-endian tvarka, yra 1; tie patys du baitai little-endian tvarka — 256. Jei hex eilutė reiškia skaitinį ilgio prefiksą ar dvejetainį lauką, įterptą į šiaip tekstinius duomenis, klaidinga baitų tvarka ne tik iškreipia skaičių — ji pastumia visas tolesnes baitų pozicijas, nes įrankis dabar mano, kad tekstas prasideda ne toje vietoje.

3 priežastis: pusbaičių (nibble) grupavimo klaidos

Hex visada turi eiti poromis — du hex skaitmenys sudaro vieną baitą. Nelyginis hex simbolių skaičius (vienas atsitiktinis skaitmuo, kopijavimas, pametęs simbolį, prieš analizę nenuimtas priekinis 0x) pastumia kiekvieną tolesnę porą per vieną pusbaitį. Kiekvienas baitas po klaidos dekoduojamas į visiškai kitą, nesusijusį simbolį — rezultatas ne „šiek tiek klaidingas“, o nuo tos vietos visiškai sujauktas. Tai iš tikrųjų naudinga diagnostika: šiukšlės, kurios prasideda švariai ir sugenda eilutės viduryje, rodo grupavimo klaidą būtent toje pozicijoje, o ne kodavimo problemą (kuri gadina tolygiau visą tekstą).

4 priežastis: nematomi ir nespausdinami baitai

Ne kiekvienas baitas atitinka matomą simbolį. Valdymo simboliai (0x00–0x1F), baitų tvarkos žymė (EF BB BF UTF-8 formatu) ir įvairūs Unicode formatavimo simboliai dekoduojami „sėkmingai“, bet, priklausomai nuo šrifto, atvaizduojami kaip niekas, kvadratėlis ar klaustukas — o tai gali atrodyti lygiai kaip dekodavimo klaida, nors pati konversija buvo visiškai teisinga. Jei išvesties ilgis atrodo teisingas, bet tekste tarsi trūksta simbolių, prieš kaltindami dekodavimo logiką patikrinkite, ar nėra valdymo baitų.

Greitas būdas nustatyti, su kuria priežastimi susidūrėte

  1. Patikrinkite, ar hex eilutėje lyginis simbolių skaičius — jei ne, tai 3 priežastis, pirmiausia pataisykite įvestį.
  2. Pirmiausia pabandykite dekoduoti kaip UTF-8, tada kaip Latin-1, ir palyginkite — jei vienas duoda švarų tekstą, o kitas ne, tai buvo 1 priežastis.
  3. Jei rezultatas tolygiai iškraipytas nuo pat pirmo simbolio, įtarkite kodavimą (1 priežastis); jei prasideda švariai ir sugenda viduryje — grupavimo klaidą (3 priežastis) toje pozicijoje.
  4. Jei ilgis atitinka lūkesčius, bet konkretūs simboliai dingę ar rodomi kaip kvadratėliai, tikrinkite valdymo/formatavimo baitus (4 priežastis), o ne iš naujo kodavimą.

Pats hex konvertavimas į tekstą — viena kodo eilutė bet kuria kalba; tikrasis derinimo darbas beveik visada yra išsiaiškinti, kuri iš šių keturių prielaidų tyliai buvo klaidinga, o ne pati konversijos logika.

← Grįžti į tinklaraštį