如何辨識奇怪的角色?

如何辨識奇怪的角色?

我試圖識別在我正在使用的文件中發現的一個奇怪的字元:

$ cat file
$ od file
0000000 005353
0000002
$ od -c file
0000000 353  \n
0000002
$ od -x file
0000000 0aeb
0000002

該檔案使用 ISO-8859 編碼,無法轉換為 UTF-8:

$ iconv -f ISO-8859 -t UTF-8 file
iconv: conversion from `ISO-8859' is not supported
Try `iconv --help' or `iconv --usage' for more information.
$ iconv  -t UTF-8 file
iconv: illegal input sequence at position 0
$ file file
file: ISO-8859 text

我的主要問題是如何解釋od這裡的輸出?我正在嘗試使用這一頁這讓我可以在不同的字元表示之間進行轉換,但它告訴我,005353作為「十六進位代碼點」似乎不正確,而0aeb作為「十六進位代碼點」似乎又是錯誤的。

那麼,我如何使用三個選項(3550053530aeb)中的任何一個來找出它們應該代表什麼字元?

是的,我確實嘗試過使用 Unicode 工具,但它似乎也不是有效的 UTF 字元:

$ uniprops $(cat file)
U+FFFD ‹�› \N{REPLACEMENT CHARACTER}
    \pS \p{So}
    All Any Assigned Common Zyyy So S Gr_Base Grapheme_Base Graph X_POSIX_Graph
       GrBase Other_Symbol Print X_POSIX_Print Symbol Specials Unicode

如果我理解 Unicode U+FFFD 字符的描述,它根本不是真正的字符,而是損壞字符的佔位符。這是有道理的,因為該檔案實際上不是 UTF-8 編碼的。

答案1

您的檔案包含兩個位元組,十六進位的 EB 和 0A。該檔案可能使用每個字元一個位元組的字元集,例如ISO-8859-1;在該字元集中,EB 是 ë:

$ printf "\353\n" | iconv -f ISO-8859-1
ë

其他候選者將是 δ代碼頁 437, Ù 在代碼頁 850

od -x在這種情況下,由於位元組序的原因, 的輸出會令人困惑;更好的選擇是-t x1使用單一位元組:

$ printf "\353\n" | od -t x1
0000000 eb 0a
0000002

od -x映射到od -t x2一次讀取兩個字節,並在小端系統上以相反的順序輸出位元組。

當您遇到這樣的檔案時,它不是有效的 UTF-8(或解釋為 UTF-8 檔案時沒有任何意義),沒有萬無一失的方法來自動確定其編碼(和字元集)。上下文可以提供幫助:如果它是過去幾十年在西方 PC 上產生的文件,那麼它很可能以 ISO-8859-1、-15(歐洲變體)或 Windows-1252 進行編碼;如果比這個更老,CP-437 和 CP-850 可能是候選人。來自東歐系統、俄羅斯系統或亞洲系統的文件將使用我不太了解的不同字元集。然後是 EBCDIC...iconv -l將列出所有已知的字元集iconv,您可以從那裡進行嘗試和錯誤。

(有一次我把 CP-437 和 ATASCII 的大部分內容都背下來了,那是日子。)

答案2

請注意,這od是縮寫八進制轉儲005353兩個位元組作為八進位字,od -x0aeb十六進製作為字,文件的實際內容是兩個位元組eb0a十六進制,按這個順序。

所以0053530aeb不能只解釋為「十六進位代碼點」。

0a是換行符 (LF),eb取決於您的編碼。file只是猜測編碼,它可以是任何東西。如果沒有任何進一步的信息,文件來自何處等,將很難找到。

答案3

不可能 100% 準確地猜測文字檔案的字元集。

類似的工具沙代,火狐瀏覽器,文件-i當沒有定義明確的字元集資訊時(例如,如果 HTML 在頭部包含元 charset=... ,事情會更容易)將嘗試使用啟發式方法,如果文字足夠大,那麼啟發式方法還不錯。

下面,我將使用chardetpip install chardet/apt-get install python-chardet如有必要)演示字元集檢測。

$ echo "in Noël" | iconv -f utf8 -t latin1  | chardet
<stdin>: windows-1252 with confidence 0.73

在獲得良好的候選字符集後,我們可以使用iconvrecode類似的方法將文件字符集更改為“活動”字符集(在我的例子中為utf-8),然後看看它是否猜測正確.... ..

iconv -f windows-1252  -t utf-8 file

一些字符集(如 iso-8859-3、iso-8859-1)有許多共同的字符——有時很難看出我們是否找到了完美的字符集...

因此,擁有與相關文字(例如 XML)相關聯的元資料非常重要。

答案4

#!/bin/bash
#
# Search in a file, a known (part of a ) String (i.E.: Begrüßung),
# by testing all encodings
#
[[ $# -ne 2 ]] && echo "Usage: encoding-finder.sh FILE fUnKy_CHAR_FOR_SURE_IN_FILE" && exit
FILE=$1
PATTERN=$2
for enc in $( iconv -l | sed 's/..$//') 
do 
    iconv -f $enc -t UTF-8 $FILE  2>/dev/null | grep -m 1 $PATTERN && echo $enc 
done 

如果我得到一個文件,其中包含例如單字 Begrung,我可以推斷可能意味著 Begrüßung。因此,我透過所有已知的編碼對其進行轉換,然後查看是否找到了正確轉換的編碼。

通常,有多種似乎合適的編碼。

對於較長的文件,您可以剪切一個片段,而不是轉換數百頁。

所以我會稱之為

encodingfinder.sh FILE Begrüßung

腳本測試是否透過使用已知編碼進行轉換,其中哪些會產生「Begrüßung」。

要找到這樣的角色,少一點通常會有幫助,因為時髦的角色往往很引人注目。從上下文中,通常可以推斷出要搜尋的正確單字。但我們不想用十六進制編輯器檢查這是什麼字節,然後訪問無盡的編碼表來找到我們的罪犯。 :)

相關內容