如何识别奇怪的角色?

如何识别奇怪的角色?

我试图识别在我正在使用的文件中发现的一个奇怪的字符:

$ 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”。

要找到这样的角色,少一点通常会有帮助,因为时髦的角色往往很引人注目。从上下文中,通常可以推断出要搜索的正确单词。但我们不想用十六进制编辑器检查这是什么字节,然后访问无尽的编码表,以找到我们的罪犯。 :)

相关内容