为什么GNU Diff不理解UTF-16(只有UTF-8)?

时间:2018-04-15 21:00:43

标签: unicode diff utf-16 git-diff byte-order-mark

为什么GNU Diff不理解UTF-16(只有UTF-8)?

默认情况下,这个GNU Diff在Git中使用。

为什么这个bug没有得到修复?

BOM是Unicode标准的一部分。 http://www.unicode.org/faq/utf_bom.html#bom4

为什么大多数程序员都忽略了BOM?

在Windows中,默认情况下会对某些源文件使用UTF-16编码。

2 个答案:

答案 0 :(得分:1)

https://lists.gnu.org/archive/html/bug-diffutils/2018-04/msg00009.html

  

UTF-8不需要BOM,但对于UTF-16和UTF-32,BOM始终存在。不带BOM的UTF-16和UTF-32文件应标识为二进制文件。

     

但为什么没有计划支持UTF-16和UTF-32? Diff是Git的一部分,在世界各地都有使用。现在2018年,Unicode解决了编码问题。

https://lists.gnu.org/archive/html/bug-diffutils/2018-04/msg00011.html

  
    

为什么没有计划支持UTF-16和UTF-32?

  
     

没有人自愿这样做,并没有迫切需要。 UTF-16和UTF-32主要用于内部表示,而不是用于文本文件。有关该主题的更多信息,请参阅:

     

http://utf8everywhere.org/

答案 1 :(得分:0)

这在GNU diffutils文档,第18.1.1节“处理多字节和变宽字符”中进行了解释:

  

diffdiff3sdiff将每行输入视为一串unibyte   字符。在某些情况下,这可能会错误处理多字节字符。对于   例如,当要求忽略空格时,diff没有正确忽略空格   多字节空间字符。

     

此外,diff目前假设每个字节都是一列宽,并且   这种假设在某些语言环境中是不正确的,例如,使用的语言环境   UTF-8编码。这会导致-y--side-by-side出现问题   diff的选项。

     

这些问题需要修复而不会过度影响   unibyte环境中的实用程序的性能。

     

IBM GNU / Linux技术中心国际化团队   提议Handbook of Applied Cryptography。不幸,   这些补丁不完整,属于diff的旧版本,所以   在这方面还需要做更多的工作。

它没有完全正确处理UTF-8,所以它不能处理UTF-16就不足为奇了。

(您可以使用识别UTF-16的区域设置来缓解此问题。我在任何使用的系统上都没有这样的区域设置,包括Windows 10下的Cygwin。)

我看到的一个问题是BOM无法识别为文本。您可以使用-a选项部分解决此问题,该选项强制diff假设其输入文件为文本。当我使用带有BOM和Windows样式行结尾的两个little-endian UTF-16文本文件时,我得到:

$ diff hello.txt hello2.txt
Binary files hello.txt and hello2.txt differ
$ diff -a hello.txt hello2.txt 
1c1
< ��hello
---
> ��Hello
$

输出是UTF-8 / ASCII,UTF-16和垃圾的混合。

(我怀疑其根本原因是UTF-16对Windows非常具体,而GNU diffutils的维护者并不关心Windows。)

大多数程序员都忽略了BOM,因为它不是UTF-8所必需的。