如何将未知的 8 位文件转换为 utf8

如何将未知的 8 位文件转换为 utf8

我有一个 .srt 文件,当我在 ubuntu 中的 gEdit 中打开它时,该文件显示为乱码。所以我想将其转换为utf8以便能够读取它。

当我试图找出它给出的编码时:

file -i x.srt 
x.srt: text/plain; charset=unknown-8bit

在另一次尝试中我发现:

find .  -type f -print | xargs file
./x.srt:   Non-ISO extended-ASCII text, with CRLF line terminators

我也尝试过 enca:

enca x.srt 
enca: Cannot determine (or understand) your language preferences.
Please use `-L language', or `-L none' if your language is not supported
(only a few multibyte encodings can be recognized then).
Run `enca --list languages' to get a list of supported languages.

enca -L Persian  x.srt 
enca: Cannot determine (or understand) your language preferences.
Please use `-L language', or `-L none' if your language is not supported
(only a few multibyte encodings can be recognized then).
Run `enca --list languages' to get a list of supported languages.

所以我想知道如何知道编码并最终将其转换为可用的格式。

答案1

没有可靠的方法将未知编码转换为已知编码。

就您而言,如果您知道原始文本是波斯语/波斯语,也许您可​​以识别许多可能的编码,并迭代这些编码,直到看到您期望的输出。

基于快速谷歌搜索,没有标准的、稳定的传统转换器伊朗系统编码,唯一剩下的流行替代方案是Windows 代码页 1256。我已经包括了阿拉伯语这里主要用于说明目的(尽管它甚至可能是波斯语的可行替代方案?)

for encoding in cp1256 macarabic; do
    if iconv -f "$encoding" -t utf-8 inputfile >outputfile."$encoding"; then
        echo "$encoding: possible"
    else
        echo "$encoding: skipped"
        rm outputfile."$encoding"
    fi
done

(我的版本iconv实际上并不支持 MacArabic,但也许你会更幸运;或者你可以尝试不同的转换工具。)

检查生成的输出文件;看看其中之一是否有意义。

如果您知道输出应该是什么样子,您还可以在文件中查找字节的单独映射。如果第一个字节是 0x94 并且您知道它应该显示为 ﭖ 您基本上已经确定编码是伊朗系统。也许再查几个字节来验证这个结论。此编码的维基百科页面有一个包含所有字符的表。显然,这是费力、缓慢且容易出错的过程,尤其是在有许多候选编码可供选择的情况下。

对于某些编码,您可以找到一个列表,例如https://tripleee.github.io/8bit/——对于其他人,也许你只需要查看相应的维基百科编码表即可。

答案2

未知 8 位代码页中的文件被确定为“未知 8 位”是有原因的:如果没有任何关于语言的想法,这不是一个简单的问题。并不是说这是不可能的,但是为了有效地工作,这种启发式检测器必须拥有所有最常用语言的大量词汇、大量代码页列表,并且了解一些语法。更新:从未尝试过enca;可能这是一个按照这些思路制作的神奇解码器。但是,如果文件表示大部分 ASCII 源代码,只有一两个由高位组八位组组成的单词,那么即使使用如此神奇的启发式算法,实际上也无法猜测语言和编码。这就是为什么原始 HTTP/1.1 强烈坚持在 HTTPContent-Type:标头中为任何text/媒体类型声明字符集。

因此,解决方案分以下几点:

  1. 调查/学习/猜测文件应该编码哪种语言。在这里,人类的智慧至关重要。至少列出一些看似合理的假设。
  2. 编译语言使用的编码列表。
  3. 尝试这些编码:head文件 |iconv -f尝试(假设根据所使用的TUI设置了LANG环境变量)并查看结果是否可读,直到成功。

当然,该解决方案假设文本已编码适当地但在一个未知代码页。由于人为错误或软件故障而导致文本乱码的情况无法通过这种方式解决。

第 2 点和第 3 点可能是自动化的,并且确实存在此类工具,但它们是特定于语言的(即俄语的启发式解码器不适用于日语,反之亦然),或者至少需要指定输入语言(如enca做)。

至于波斯语,可能的编码包括 Windows-1256(请参阅这个线程)、ISO 8859-6,现已废弃伊朗系统编码。值得高兴的是,您没有至少七个用于俄语的代码页的列表(KOI7、KOI8、CP866、Windows-1251、ISO 8859-5、MacCyrillic、MIK)。

答案3

也许可以通过列出每个的前 20 行来直观地检查 iconv 的所有 ~1000 种可能性...合并到 all.txt 结果中。

#!/usr/bin/env bash
                      line=$(printf "=%.0s" {1..50})
for FMT in $(iconv -l); do    
                   echo "$line\nFormat $FMT:\n$line"
   iconv -f $FMT -t UTF8 < inputFile.srt | head -n20
done > all.txt

#gedit all.txt

...并找出哪种格式是正确的(如果您能识别波斯语)。

相关内容