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
,005353
或0aeb
)中的任何一个来找出它们应该代表什么字符?
是的,我确实尝试过使用 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 的大部分内容都熟记于心,这些日子已经过去了。)
请注意,od
是短期的八进制转储,所以005353
是两个字节为八进制字,od -x
是0aeb
十六进制的话,你的文件的实际内容是两个字节eb
,并0a
以十六进制,在这个秩序。
因此,无论005353
而0aeb
不能仅仅被理解为“十六进制代码点”。
0a
是换行符 (LF),eb
取决于您的编码。file
只是猜测编码,它可以是任何东西。如果没有文件来自何处的任何进一步信息,将很难找到。