ব্রাউজারে চলা বাইনারি এডিটর তৈরির গল্প
বাইনারি এডিটর কী?
বাইনারি এডিটর হল এমন এক টুল যা ফাইলকে ১৬-ভিত্তিক (Hex) কিংবা ASCII আকারে সরাসরি সম্পাদনা করতে দেয়। সাধারণ টেক্সট এডিটর যেখানে “স্ট্রিং” সম্পাদনা করে, সেখানে বাইনারি এডিটর ফাইলের “কাঁচা বাইট ধারার” কাছে পৌঁছে ইচ্ছামতো অবস্থানের বিট বা বাইট বদলাতে পারে।
সফটওয়্যার বিশ্লেষণ, ডেটা উদ্ধার, প্রোটোকল অনুসন্ধান—এসব ক্ষেত্রে বাইনারি এডিটর অপরিহার্য। GUI অ্যাপ হিসেবে HxD
বা Binary Ninja
এর মতো টুল বিখ্যাত। কিন্তু আমার লক্ষ্য ছিল “শুধু ব্রাউজারে চলা, একক HTML ফাইলের বাইনারি এডিটর” তৈরি করা।
বাস্তবায়নের নীতি
- পুরোপুরি ক্লায়েন্ট-সাইড (কোনো বাহ্যিক পাঠানো নেই)
FileReader
API দিয়ে লোকাল ফাইল পড়া- বাম পাশে Hex, ডানে ASCII দেখানো
- সেলে ক্লিক করলে এডিট মোডে গিয়ে সরাসরি মান বদলানো যায়
- সম্পাদিত অংশ লাল অক্ষরে হাইলাইট
- HEX এবং ASCII এডিট মোড টগল করা যায়
- সম্পাদিত ফল আবার ফাইল হিসেবে ডাউনলোড করা যায়
যেসব জায়গায় হোঁচট খেয়ে ঠিক করেছি
১. এডিট ফ্রেমের সরে যাওয়া
প্রথম সংস্করণে সম্পাদিত সেলে হলুদ বর্ডার দিলে ফ্রেমটা খানিকটা সরে গিয়ে অস্বস্তিকর লাগছিল। কারণ ছিল CSS এর line-height
আর flex
লেআউট—দেখানো অক্ষর আর ফ্রেমের ভিত্তি বিন্দু এক ছিল না। মনোস্পেস ফন্ট ধরেই ডিজাইন করেছিলাম, কিন্তু ব্রাউজারের রেন্ডারিং প্রসেসে ফন্টভেদে বেসলাইন বদলায়, ফলে ফ্রেম কখনো ওপরের দিকে কখনো নিচে ভেসে যাচ্ছিল।
vertical-align: middle
বাধ্যতামূলক করে, পাশাপাশি display: inline-block
দিয়ে উচ্চতা মিলিয়ে নেওয়ায় সমস্যার সমাধান হয়।
.hex-cell.editing {
outline: 2px solid yellow;
vertical-align: middle;
}
২. ESC চাপলে অদ্ভুত অক্ষর ঢুকে যাওয়া
প্রথমে এডিট বক্স সক্রিয় রেখে ESC চাপলে সেলে “EE” জাতীয় অক্ষর ঢুকে যাচ্ছিল।
কারণটা ছিল আমরা keydown
ইভেন্ট ধরছিলাম না, ফলে ব্রাউজার চাপা কী-এর কোড সরাসরি সেল সম্পাদনার প্রক্রিয়ায় চলে যাচ্ছিল। স্বাভাবিক ইনপুটে 0–9 আর A–F ধরা হয়েছিল, কিন্তু Escape
কী-এরও কোড থাকে (পুরনো বাস্তবায়নে keyCode=27
, নতুন স্পেসিফিকেশনে key="Escape"
)। সেটাই ইনপুট হ্যান্ডলার ধরে "E"
হিসেবে বোঝে, ফলে "EE"
লিখে ফেলত।
সমাধান সহজ—keydown
এ Escape
সুনির্দিষ্টভাবে ধরতে হবে এবং সেলের সম্পাদনা বাতিল করতে হবে।
document.addEventListener("keydown", e => {
if (e.key === "Escape") {
cancelEdit();
e.preventDefault(); // মূল ইনপুট রুটে যেতে দেব না
}
});
এতে ESC এখন শুধু “সম্পাদনা বাতিল” কাজ করে; সেলে আর অক্ষর ঢুকে না।
৩. নতুন ফাইল লোডেও লালচে দাগ থেকে যাওয়া
একবার ফাইল লোড করে সম্পাদনা করার পর অন্য ফাইল খুললে আগের লাল হাইলাইট থেকে যাচ্ছিল।
কারণ ছিল সম্পাদিত সেল ট্র্যাক করার অ্যারে ও স্টেট ফাইল লোডের সময় রিসেট হচ্ছিল না। শুধু প্রদর্শনের এলাকা ক্লিয়ার করলেও ভেতরের “পরিবর্তন ফ্ল্যাগ” থেকে যাচ্ছিল, তাই নতুন ফাইলেও লাল অবস্থা বহাল থাকত।
ফাইল লোডের পর clearModifiedState()
কল করে পরিবর্তনের ফ্ল্যাগ পুরোপুরি রিসেট করায় সমস্যাটি মিটেছে।
৪. HEX/ASCII মোড টগলের প্রয়োজনীয়তা
প্রাথমিক সংস্করণে HEX আর ASCII দুটোই একসঙ্গে সম্পাদনা করা যেত। ফলে “কোনটা সঠিক” তা নিয়ে বিভ্রান্তি তৈরি হচ্ছিল। ১ বাইটকে দুটি ইনপুটে একযোগে ব্যবহারের ফলেই একই সেল আলাদা রুটে ওভাররাইট হওয়া সমস্যা দেখা দিত। ASCII ইনপুট করলে সঙ্গে সঙ্গে HEX মান বদলাত, কিন্তু মাঝপথে ইনপুট দেওয়ার সময় সাময়িক অসামঞ্জস্য দেখা যেত।
গোলযোগ এড়াতে মোড বেছে নেওয়ার জন্য স্পষ্ট সিলেক্ট বক্স যোগ করেছি এবং ডিফল্ট করেছি HEX এডিট। এতে ব্যবহারকারী বুঝতে পারে “এখন আমি HEX লিখছি”, এবং সিঙ্ক প্রক্রিয়াও সরল হলো।
কোডের একটি অংশ
বাস্তব সম্পাদনা প্রক্রিয়াটি এরকম।
function applyEdit(offset, newValue) {
if (mode === "hex") {
buffer[offset] = parseInt(newValue, 16);
} else {
buffer[offset] = newValue.charCodeAt(0);
}
markModified(offset);
render();
}
markModified(offset)
কেবল মূল মানের সঙ্গে তুলনা করে পার্থক্য হলে ক্লাস যোগ করে, যাতে লাল হাইলাইট করা যায়—খুবই সরল লজিক।
সারাংশ
এই ব্রাউজার-সংস্করণের বাইনারি এডিটর অফলাইনে চলে এবং নিরাপত্তার দিক থেকেও “সম্পূর্ণ ক্লায়েন্ট-সাইড টুল” হিসেবে নির্ভরযোগ্য।
- সামান্য বাইনারি পরিবর্তনের প্রয়োজন হলে
- বিশেষ অ্যাপ ইনস্টল করা যায় না এমন পরিবেশে তদন্ত করতে হলে
- শিক্ষা বা শেখার উদ্দেশ্যে “বাইট স্ট্রিম” হাতে-কলমে বুঝতে চাইলে
এগুলোতেই এটি কাজে লাগতে পারে।