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

时间:2011-01-11 07:38:01

标签: 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();

5 个答案:

答案 0 :(得分:274)

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

UTF-8和UTF-16都是可变长度编码。但是,在UTF-8中,一个字符可能占用至少8位,而在UTF-16中,字符长度从16位开始。

主要UTF-8职业选手:

  • 基本ASCII字符(如数字,没有重音的拉丁字符等)占用一个字节,与US-ASCII表示相同。这样,所有US-ASCII字符串都变为有效的UTF-8,在许多情况下,它提供了良好的向后兼容性。
  • 没有空字节,允许使用以空字符结尾的字符串,这也带来了很多向后兼容性。
  • 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字符串中有很多空字节,这意味着没有以空字符结尾的字符串和大量浪费的内存。
  • 在许多常见情况下(特别是在美国/欧盟/有西里尔字母/以色列/阿拉伯国家/伊朗和许多其他国家/地区的国家/地区)使用它作为固定长度编码“主要起作用”,往往会导致支持不足“T。 这意味着程序员必须了解代理对并在重要的情况下正确处理它们!
  • 它的长度可变,因此计算或索引代码点的成本很高,但低于UTF-8。

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

答案 1 :(得分:18)

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

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

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

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

有关UTF-8和Unicode的更多信息,请参阅this page

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

答案 2 :(得分:4)

这与UTF-8/16无关(一般来说,虽然它确实转换为UTF16,BE / LE部分可以用单行设置),但下面是将String转换为byte的最快方法[ ]。例如:完全适合所提供的情况(哈希码)。 String.getBytes(enc)相对较慢。

static byte[] toBytes(String s){
        byte[] b=new byte[s.length()*2];
        ByteBuffer.wrap(b).asCharBuffer().put(s);
        return b;
    }

答案 3 :(得分:0)

安全性:仅使用UTF-8

  

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

UTF-16的实现中至少存在两个安全漏洞。参见Wikipedia for details

WHATWGW3C具有now declared,只有UTF-8可以在网络上使用。

  

仅使用UTF-8时,此处概述的[安全]问题就消失了,这是现在成为所有事物强制编码的众多原因之一。

其他团体也一样。

因此,尽管Java和Windows等某些系统可能继续在内部使用UTF-16,但是您过去在数据文件,数据交换等方面可能很少使用UTF-16,这很可能会逐渐消失。完全。

答案 4 :(得分:-1)

区分UTF-8和UTF-16的简单方法是识别它们之间的共性。

除了为给定字符共享相同的unicode编号外,每个都是他们自己的格式。