如何识别一个奇怪的字符?

ter*_*don 11 character-encoding unicode

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

$ cat file
?
$ od file
0000000 005353
0000002
$ od -c file
0000000 353  \n
0000002
$ od -x file
0000000 0aeb
0000002
Run Code Online (Sandbox Code Playgroud)

该文件使用 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
Run Code Online (Sandbox Code Playgroud)

我的主要问题是如何解释od这里的输出?我正在尝试使用此页面,它可以让我在不同的字符表示之间进行翻译,但它告诉我,005353“十六进制代码点”?似乎不正确,0aeb而“十六进制代码点”?似乎又是错误的.

那么,我如何使用三个选项(355,0053530aeb)中的任何一个来找出它们应该代表什么字符?

是的,我确实尝试过使用 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
Run Code Online (Sandbox Code Playgroud)

如果我理解 Unicode U+FFFD 字符的描述,它根本不是一个真正的字符,而是一个损坏字符的占位符。这是有道理的,因为该文件实际上不是 UTF-8 编码的。

Ste*_*itt 22

您的文件包含两个字节,EB 和 0A(十六进制)。很可能该文件正在使用每个字符一个字节的字符集,例如ISO-8859-1;在该字符集中,EB 是 ë:

$ printf "\353\n" | iconv -f ISO-8859-1
ë
Run Code Online (Sandbox Code Playgroud)

其他候选人会是?在代码页 437 中,Ù 在代码页 850 中......

od -x由于字节顺序,在这种情况下的输出令人困惑;更好的选择是-t x1使用单个字节:

$ printf "\353\n" | od -t x1
0000000 eb 0a
0000002
Run Code Online (Sandbox Code Playgroud)

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 的大部分内容都熟记于心,这些日子已经过去了。)


dir*_*rkt 5

请注意,od是短期的八进制转储,所以005353是两个字节为八进制字,od -x0aeb十六进制的话,你的文件的实际内容是两个字节eb,并0a以十六进制,在这个秩序。

因此,无论0053530aeb不能仅仅被理解为“十六进制代码点”。

0a是换行符 (LF),eb取决于您的编码。file只是猜测编码,它可以是任何东西。如果没有文件来自何处的任何进一步信息,将很难找到。