犯傻摔進 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 擴充套件,還是微軟出的,以後就不捨近求遠了。


Comments

# by Allen

Madedit-Mod還不錯用:https://sourceforge.net/projects/madedit-mod/

# by 小黑

好球

# by Joseph

感謝版主這篇提醒,也讓我壓壓驚....(呼)

# by shaman

我用蠻正常的,用來改金庸群俠傳的存檔。 不過還是謝謝你的提醒。

Post a comment