Hogyan fejlesztettem egy böngészőben futó bináris szerkesztőt
Mi az a bináris szerkesztő?
A bináris szerkesztő olyan eszköz, amellyel egy fájl 16-os számrendszerű vagy ASCII nézetben, közvetlenül szerkeszthető. Míg egy hagyományos szövegszerkesztő a „karakterláncokat” kezeli, addig a bináris szerkesztő a fájl „nyers bájtsorozatához” fér hozzá, és bármely pozícióban bitet vagy bájtot módosíthatunk.
Szoftveranalízishez, adatmentéshez vagy protokollvizsgálathoz megkerülhetetlen eszköz.
Grafikus alkalmazások közül a HxD
vagy a Binary Ninja
a legismertebb, de a célom most az volt, hogy egyetlen HTML-fájlban, csupán böngészőben futó bináris szerkesztőt készítsek.
Megvalósítási irányelvek
- Teljesen kliensoldali működés (nincs külső adatküldés)
- A
FileReader
API-val olvassa be a helyi fájlokat - Bal oldalon a hexadecimális (hex), jobb oldalon az ASCII nézet jelenik meg
- Kattintás után szerkesztő módba lép, és közvetlenül átírható az érték
- A módosított cellákat piros színnel emeli ki
- Hex és ASCII szerkesztő mód között válthatunk
- A módosított tartalom fájlként letölthető
Elakadások és javítások
1. Elcsúszó szerkesztési keret
Az első verzióban a kijelölt cella köré húzott sárga keret enyhén félrecsúszott, emiatt furcsán nézett ki.
A gond az volt, hogy a CSS line-height
és a flex
elrendezés miatt a megjelenített karakter és a keret referencia pontja nem esett egybe.
Monospace betűtípusra támaszkodom, de a böngészők eltérő alapvonalat használhatnak, így a keret fel- vagy lecsúszott.
A megoldás az lett, hogy vertical-align: middle
stílust adtam, és display: inline-block
-ra váltottam, így a magasság szépen illeszkedett.
.hex-cell.editing {
outline: 2px solid yellow;
vertical-align: middle;
}
2. Az ESC billentyű karaktert ír be
Kezdetben, ha szerkesztés közben megnyomtam az ESC-et, olyan karakterek kerültek be a cellába, mint „EE”.
Ennek az volt az oka, hogy nem kezeltem külön a keydown
eseményt, így a böngésző a lenyomott billentyű kódját az inputfeldolgozásnak adta át.
A normál bevitelnél csak 0–9 és A–F karakterekre számítottam, de az Escape
billentyűnek is van kódja (keyCode=27
, az újabb szabvány szerint key="Escape"
), ami „E”-ként értelmeződött, így dupla E került a cellába.
A megoldás: a keydown
eseménynél külön ellenőrzöm, ha Escape
a lenyomott gomb, megszakítom a szerkesztést, és letiltom, hogy a billentyű az eredeti inputútvonalra kerüljön.
document.addEventListener("keydown", e => {
if (e.key === "Escape") {
cancelEdit();
e.preventDefault(); // ne fusson végig az alapértelmezett bevitel
}
});
Így az ESC már kizárólag „szerkesztés megszakítása” funkciót lát el, nem ír be karaktert.
3. Új fájl betöltésekor megmaradó piros jelölések
Ha szerkesztés után új fájlt töltöttem be, a korábbi piros kiemelések ott maradtak.
A bibi az volt, hogy a módosított cellákat nyilvántartó tömböt és állapotot nem inicializáltam újra fájlbetöltéskor. Hiába töröltem a megjelenített rácsot, a belső „változott-e” jelzők megmaradtak, ezért az új fájlon is pirosan világítottak.
Megoldásként a fájlbeolvasás elején meghívtam a clearModifiedState()
függvényt, amely mindent visszaállít alaphelyzetbe.
4. Hex/ASCII módváltás
Az első változatban egyszerre lehetett a hexet és az ASCII-t szerkeszteni, ami zavart okozott: ugyanazt a bájtot két külön útvonalon is át lehetett írni. ASCII bevitelkor azonnal frissült a hex nézet, de félig beírt karaktereknél átmenetileg inkonzisztens állapot jelent meg.
A rend kedvéért külön üzemmódot vezettem be, amelyet egy legördülő menüből lehet kiválasztani, és alapértelmezetten a hex szerkesztést hagytam meg. Így a felhasználó mindig tudja, épp milyen formátumban ír, a szinkronizáció pedig jóval egyszerűbb lett.
Kódrészlet
A tényleges szerkesztési logika valahogy így fest:
function applyEdit(offset, newValue) {
if (mode === "hex") {
buffer[offset] = parseInt(newValue, 16);
} else {
buffer[offset] = newValue.charCodeAt(0);
}
markModified(offset);
render();
}
A markModified(offset)
egyszerűen hozzárendeli a piros kiemeléshez szükséges osztályt, ha az új érték eltér az eredetitől.
Összegzés
Az elkészült böngészős bináris szerkesztő offline is működik, és a biztonság szempontjából is „teljesen kliensoldali” megoldás maradt.
- Ha csak apró bináris módosítást kell végrehajtani
- Ha olyan környezetben vizsgálódsz, ahol nem telepíthetsz dedikált alkalmazást
- Ha oktatási célból szeretnéd intuitívan megérteni a bájtsorozatokat
Ilyen helyzetekben remélhetőleg jól használható lesz.