
為什麼 Excel 在十六進位字串上只能處理十進位
Excel 的 HEX2DEC 函式會從十六進位輸入傳回十進位數字,所以一個包含 48 的儲存格會傳回 72,而不是 ASCII 字母 H。這個單一事實正是直接在 Excel 中進行十六進位到文字轉換通常會失敗的核心原因。HEX2DEC 處理的是個別的數值,而不是位元組序列,輸入上限為 10 個十六進位數字,並傳回一個十進位整數。它沒有對應的 HEX2TXT 或 HEX2UTF8,不了解多位元組的 UTF-8 編碼,也不知道要先將兩個十六進位數字配對成一個位元組,再將該位元組對應到字元。因此,任何需要將像 48656c6c6f 這樣的字串解讀為 Hello 的人,都必須在試算表內自製一個流程,而這個流程幾乎總是在第一個非 ASCII 字元處就會出錯。常見的土法煉鋼做法是對每個位元組執行 HEX2DEC,再對每個十進位數執行 CHAR,最後用 CONCAT 或 & 把字母串起來。這個流程對純 ASCII 有效,因為每個位元組都小於 128,能乾淨地對應到一個代碼點,但只要某個位元組超過 127,它就會崩潰,因為 Excel 沒有內建方法能把這些位元組送進 CHAR 並還原出有效的 UTF-8 序列。這就是當資料離開試算表後,一個獨立的瀏覽器型 UTF-8 十六進位解碼器設計來補上的實際缺口。
HEX2DEC 對輸入長度的限制是眾所周知的:超過 10 個十六進位數字會傳回錯誤,而且該函式傳回的十進位整數沒有位元組邊界的概念。CHAR 函式接受 1 到 255 的數字,並將其轉為對應的單位元組字元,但它不會把這些字元視為一個多位元組 UTF-8 序列的一部分。因此,自製的 Excel 解碼器可以還原 ASCII 文字和零散的 Latin-1 字元,但無法還原 é、€、你 或 😊,除非從頭重建編碼器。所有這些缺口,正是瀏覽器型的 Hex to Text Converter 所要補上的——它使用嚴格且具 UTF-8 感知能力的解碼器,在本地端處理你從 Excel 複製出來的任何十六進位資料。
如何從 Excel 取出十六進位資料以供瀏覽器解碼
第一個實際問題是如何將十六進位資料從 Excel 儲存格移到此工具的輸入欄。幾乎所有你會遇到的試算表都可以用以下三種模式涵蓋。
模式一是「一格一個位元組」:一整欄的兩個字元十六進位字串,例如 48、65、6c、6c、6f。選取範圍、複製,然後貼到工具中。在啟用空白字元分隔符的純文字模式下,工具會將其接受為五個等長的十六進位群組,以 ASCII 空白分隔。模式二是「一格多位元組」:單一儲存格包含 48656c6c6f。這與第一個模式的內容相同,只是連在一起。因為每個群組只需要只包含十六進位數字,並且數字數量為偶數,所以工具會將其接受為一個連續的等長群組。模式三是「一格、程式碼風格的標記」:儲存格包含 0x48 0x65 0x6c 0x6c 0x6f,這是許多語言和資料庫用戶端匯出二進位常值的方式。在啟用前綴的模式下,當前綴被啟用且該選項強制採用精確的 0xNN 標記形狀時,工具就會接受這種格式。
Excel 的「文字剖析」精靈可以依據地區設定,以逗號、空格、Tab、分號或直立線符號來輕鬆分割第二和第三種模式。如果你不需要分割,就不要執行它;將儲存格內容以單一字串複製,然後直接貼到工具中。如果某個十六進位值在 Excel 中帶有前置撇號(這是試算表強制將其視為文字的方式),這個撇號不屬於字串的一部分,Excel 在複製時會將其去除,因此你不需要再手動去除。你真正需要去除的是 Excel 在將看起來像十六進位的字串解讀為公式時所加的前置等號;工具會拒絕任何不是十六進位數字、已啟用分隔符或已啟用 0x 前綴的字元。
如何使用瀏覽器工具將十六進位轉換為文字
- 在你用於試算表的同一個瀏覽器分頁中開啟 Hex to Text Converter。頁面載入時,兩個語法選項都是預設值:允許 ASCII 空白,允許 0x 前綴。
- 將你的十六進位貼到輸入欄。如果你的 Excel 儲存格包含 48656c6c6f,就原樣貼上。如果你的儲存格包含 48,65,6c,6c,6f,可以在以逗號執行「文字剖析」後重新貼上,然後再貼上合併後的結果;或者自己手動移除逗號——剖析器只把已啟用的 ASCII 空白視為分隔符,會直接拒絕逗號。
- 確認語法選項。除非你的十六進位完全沒有分隔符,且你想禁止任何多餘的分隔符,否則請保持啟用 ASCII 空白。除非你的標記都不是以 0x 開頭,否則請保持啟用前綴;如果停用前綴,任何意外出現的 0x 都會被拒絕,而不是被默默忽略。
- 按一下「解碼」。工具會在唯讀欄位中回報位元組數和解碼後的文字。位元組數是剖析器接受的位元組數,而不是十六進位數字的數量。
- 如果欄位顯示錯誤,請修正第一個被回報的問題,然後再次解碼。編輯輸入或更改任一選項會立即清除先前的輸出,因此過時的文字絕不會與新的錯誤並存。
- 如果你的瀏覽器允許存取剪貼簿,請使用複製按鈕複製解碼後的文字,或自行選取並複製。用 Ctrl+V 將其貼回單一 Excel 儲存格中。
接受的十六進位格式與 Excel 儲存格值的比較
下表顯示剖析器接受的內容,以及典型的 Excel 儲存格值對照。「Excel 儲存格值」欄描述的是會出現在資料編輯列中的字面字串;「工具結果」欄描述的是瀏覽器工具對從 Excel 複製出來的該確切字串的處理結果。
| Excel 儲存格值 | 工具結果 |
|---|---|
| 48656c6c6f | 解碼為 Hello (5 個位元組) |
| 48 65 6c 6c 6f | 在啟用空白時解碼為 Hello (5 個位元組) |
| 0x48 0x65 0x6c 0x6c 0x6f | 在啟用前綴時解碼為 Hello (5 個位元組) |
| 48,65,6c,6c,6f | 錯誤:逗號不是已啟用的分隔符 |
| 4 8 65 6c 6c 6f | 錯誤:4 和 8 是奇數長度的群組 |
| 48g65 | 錯誤:g 不是十六進位數字 |
| EFBBBF41 | 解碼為 A,前導 3 位元組 BOM 已被消耗 |
| 48 | 解碼為 H (1 個位元組) |
任何一對小資料都能快速驗證:4869 解碼為 Hi,因為 0x48 等於 72,也就是 H 的 ASCII 碼;0x69 等於 105,也就是 i 的 ASCII 碼。兩者都是單位元組 UTF-8 序列,所以這兩個位元組合起來就是這兩個字元。
常見的 Excel 十六進位陷阱,以及工具如何捕捉它們
當十六進位資料從公式鏈匯出時,半位元組數錯誤是最常見的失敗。當 CHAR 呼叫傳回的代碼點不是一個完整的 UTF-8 序列時,Excel 並不會發出警告,因此自製的編碼器可能會悄悄產生一個看起來沒問題的孤立續接位元組。工具會在解碼時拒絕該位元組,並回傳「未解碼任何內容」的精確措辭,如此便可追溯回產生該錯誤列的公式。第二個陷阱是 BOM:以 CSV UTF-8 格式從 Excel 儲存的活頁簿會在開頭加上 EF BB BF,這個前綴是一個有效的 UTF-8 位元組順序標記。工具會將其消耗掉,因為標準的 TextDecoder 包裝器採用其預設的 ignoreBOM false 行為,這意味著 EF BB BF 41 會變成 A,而不是 U+FEFF 接著 A。同樣的位元組若出現在較長序列的中間,則會被保留為字面的 U+FEFF 字元,這就是為什麼位置很重要。
第三個陷阱是混用語法。由不同公式產生的儲存格可能同時帶有 0x 前綴和裸標記的混合,剖析器會拒絕解讀 0x41 42,因為它無法判斷 42 是純粹的十六進位還是只去掉一半的前綴。解決方法是為匯出選擇一種語法並堅持使用:在複製到純文字模式之前,先移除所有 0x 前綴;或者在複製到前綴模式之前,將每個位元組填補為 0xNN 的形狀。第四個陷阱是隱形的空白字元。當從網路來源匯入值時,Excel 會毫不猶豫地把不斷行空白字元貼到儲存格中,而工具會直接拒絕任何非 ASCII 的空白字元。請在 Excel 中使用 TRIM 和 CLEAN 來取代這些字元,或者先將儲存格複製到記事本中,以便看出一般空格與不斷行空白的差異。
容量上限是明確的。工具接受最多 2,000,000 個 UTF-16 代碼單位的原始輸入、最多 1,000,000 個剖析後的位元組,以及最多 1,000,000 個 UTF-16 代碼單位的解碼後文字。前綴標記法每個位元組會使用較多的來源字元,因此來自大型試算表、以 0x 前綴匯出的資料,可能會在到達位元組上限之前就先達到原始輸入上限;這是預期的情況,並會以相同的「未解碼任何內容」措辭回報。不會有任何值被默默截斷,任何超大的來源都不會被切割,而且位元組數是在配置之前計算的,因此容量錯誤絕不會產生部分輸出。
此工具只解碼 UTF-8。它不會猜測 Windows-1252、ISO-8859-1、UTF-16 或 Shift_JIS,因為默默猜測會改變位元組的意義,這正是促使我們設計嚴格解碼器的失敗模式。這些檢查遵循 WHATWG UTF-8 解碼器和 RFC 3629,而不是寬鬆的位元組到代碼單位的捷徑。如果你的 Excel 匯出來自舊版活頁簿,解碼後的文字看起來不對,那些位元組幾乎可以肯定不是 UTF-8,正確的下一步是確認來源編碼,而不是去尋找解碼技巧。對於 UTF-8 十六進位資料,工作流程是:從 Excel 複製,貼到工具中,解碼,複製結果,再貼回。三個步驟,沒有公式,沒有伺服器上傳,沒有默默出現的替代字元。
如果你正在權衡各種方案,文字隱寫術解析:零寬度 Unicode 基礎對此有詳細介紹。
如果你正在權衡各種方案,在 Excel 中將文字轉為二進位:超越 BASE 函式對此有詳細介紹。