0

Notepad++ Hex Editor 陷阱

 2 years ago
source link: https://blog.darkthread.net/blog/npp-hex-editor-pitfall/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Notepad++ Hex Editor 陷阱

2022-02-20 02:10 PM 1 1,738

犯傻摔進 Notepad++ Hex Editor 的大坑,陷在裡面兩小時,好不容易爬上來,快寫篇筆記壓壓驚。

這兩天在修復古蹟,試圖重現 30 年前用 Turbo Pascal 寫的俄羅斯方塊,當年還很用心做了背景音樂用主機板的內建喇叭播單音弦律,但音樂檔遺失無緣重溫。查程式碼找出資料規格,我想用 C# 復刻俄羅斯方塊背景音樂補上。

當年的資料檔採二進位格式(30 年前沒聽過 XML、JSON),我用 FileStream.Write(byte[], startIndex, length) 寫入資料,處理完想看檢查內容,我想到 Notepad++ 有裝 Hex Editor 可以看檔案二進位內容,卻發現檔案內容錯亂,以為哪裡寫錯了或是 FileStream.Write() 方法有我不知道的眉角,鬼打牆半天,最後發現問題出在 Notepad++ 身上。用以下的程式重現問題:

using (var f = new FileStream("TEST1.BIN", FileMode.Create))
{
    Action<int> writeInt = (v) =>
    {
        var b = BitConverter.GetBytes((short)v);
        f.Write(b, 0, b.Length);
    };
    for (int i = 0; i < 4; i++)
        writeInt(i);
}

using (var f = new FileStream("TEST2.BIN", FileMode.Create))
{
    Action<int> writeInt = (v) =>
    {
        var b = BitConverter.GetBytes((short)v);
        f.Write(b, 0, b.Length);
    };
    writeInt(178);
    for (int i = 0; i < 4; i++)
        writeInt(i);
}

兩段程式都要寫入一段二進位內容 01 00 02 00 03 00 04 00,差別在 TEST2.BIN 最前面會多加兩個 Byte B2 00。用 Notepad++ Hex Editor 檢視,讓人大吃一驚:

TEST1.BIN 的內容符合預期,但 TEST2.BIN 卻是 C2 B2 00 01 02 03 只有 6 Bytes,最前面還出現不知哪冒出來的 C2。再做了一些實驗,大致推測是 Notepad++ 在開啟檔案時會嘗試當成文字檔解析,自動轉換 UTF-8、Unicode、中文編碼,以方便使用者閱讀,畢竟 Notepad++ 原本的角色是文字編輯器。當硬用它解析二進位檔案,便可能因編碼識別及轉換而失真。以下是更明顯的例子,我產生 16 進位內容 41 00 42 00 43 00 (0x41、42、43 對映到字元 A B C),Notepad++ 識別出 ABC,Hex Edtitor 看到的長度 3 是字元長度非原始資料長度:

這個坑踩一次就知道了,Notepad++ Hex Editor 查查中文編碼還行,拿來開純二進位資料檔是自找麻煩。那有沒有好用的 Hex Editor 呢?

你為什麼不問問神奇海螺用 VSCode 呢?VSCode 有 Hex Editor 擴充套件,還是微軟出的,以後就不捨近求遠了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK