UTF-8和UTF-16之间的区别?

the*_*ava 134 java unicode utf-8 utf-16 utf

UTF-8和UTF-16之间的区别?我们为什么需要这些?

MessageDigest md = MessageDigest.getInstance("SHA-256");
String text = "This is some text";

md.update(text.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();
Run Code Online (Sandbox Code Playgroud)

Ser*_*nov 279

我相信网上有很多关于这方面的好文章,但这里有一个简短的总结.

UTF-8和UTF-16都是可变长度编码.但是,在UTF-8中,字符可能占用最少8位,而在UTF-16中,字符长度以16位开始.

主要UTF-8专业人士:

  • 数字,没有重音的拉丁字符等基本ASCII字符占用一个字节,与US-ASCII表示相同.这样,所有US-ASCII字符串都变为有效的UTF-8,在许多情况下,它提供了良好的向后兼容性.
  • 没有空字节,允许使用以null结尾的字符串,这也引入了大量的向后兼容性.
  • UTF-8独立于字节顺序,因此您不必担心Big Endian/Little Endian问题.

主要UTF-8缺点:

  • 许多常见字符具有不同的长度,这会减慢代码点的索引并极大地计算代码点计数.
  • 尽管字节顺序无关紧要,但有时UTF-8仍然具有BOM(字节顺序标记),用于通知文本以UTF-8编码,并且即使文本仅包含ASCII字符,也会破坏与ASCII软件的兼容性.Microsoft软件(如记事本)特别喜欢将BOM添加到UTF-8.

主要UTF-16专业人士:

  • BMP(基本多语言平面)字符,包括拉丁语,西里尔语,大多数中文(中华人民共和国支持BMP强制以外的一些代码点),大多数日语可以用2个字节表示.这将加快索引和计算代码点计数情况下,文中包含增补字符.
  • 即使文本具有补充字符,它们仍然由成对的16位值表示,这意味着总长度仍然可以被2整除,并允许使用16位char作为字符串的基本组件.

主要UTF-16缺点:

  • US-ASCII字符串中有很多空字节,这意味着没有以空字符结尾的字符串和大量浪费的内存.
  • 在许多常见情况下(特别是在美国/欧盟/有西里尔字母/以色列/阿拉伯国家/伊朗和许多其他国家/地区的国家/地区)使用它作为固定长度编码"主要起作用",往往会导致支持不足.这意味着程序员必须了解代理对并在重要的情况下正确处理它们!
  • 它的长度可变,因此计算或索引代码点的成本很高,但低于UTF-8.

一般来说,UTF-16通常更适合内存中表示,因为BE/LE与那里无关(只使用本机顺序)并且索引更快(只是不要忘记正确处理代理对).另一方面,UTF-8非常适用于文本文件和网络协议,因为没有BE/LE问题,并且空终止通常会派上用场,并且兼容ASCII.

  • 是的,我忘记了BE/LE.但这并不是什么大问题,特别是对于内存使用.仅当涉及三字节字符时,UTF-8才会生成更长的输出,但这意味着大多数是中文和日文.另一方面,如果文本包含许多US-ASCII字符,它可能会产生较短的输出,因此它是否是缺点取决于特定情况. (4认同)
  • 缺少UTF16上的BE/LE部分:) UTF-8有另一个缺点,它可能产生比UTF16更长的输出 (2认同)

Jon*_*eet 18

它们只是表示Unicode字符的不同方案.

两者都是可变长度的 - UTF-16对基本多语言平面(BMP)中的所有字符使用2个字节,其中包含常用的大多数字符.

对于BMP中的字符,UTF-8使用1到3个字节,对于U + 0000到U + 1FFFFF的当前Unicode范围内的字符最多使用4个字符,如果有必要,可扩展到U + 7FFFFFFF ...但值得注意的是,所有ASCII字符均以单字节表示.

出于消息摘要的目的,只要尝试重新创建摘要的每个人都使用相同的选项,您选择哪一个都无关紧要.

有关UTF-8和Unicode的更多信息,请参阅此页面.

(请注意,所有Java字符都是BMP中的UTF-16代码点;要表示U + FFFF以上的字符,您需要在Java中使用代理项对.)


Bas*_*que 7

安全性:仅使用 UTF-8

UTF-8 和 UTF-16 的区别?为什么我们需要这些?

UTF-16 的实现中至少存在几个安全漏洞。有关详细信息,请参阅维基百科

WHATWGW3C现正在申报只有UTF-8要在Web上使用。

当仅使用 UTF-8 时,此处概述的 [安全] 问题会消失,这是现在所有事物都必须进行编码的众多原因之一。

其他团体也说同样的话。

因此,尽管 UTF-16 可能会继续在某些系统(例如 Java 和 Windows)内部使用,但您过去可能很少看到 UTF-16 用于数据文件、数据交换等,但很可能会完全消失。