精华内容
下载资源
问答
  • Unicode UTF-8UTF-16、UTF-32之间的关系

    千次阅读 多人点赞 2019-03-15 21:41:05
    Unicode UTF-8UTF-16、UTF-32之间的关系 要厘清它们之间的关系就要先从编码开始说起: ASCII码 我们都知道,在计算机的世界里,信息的表示方式只有 0 1,但是我们人类信息表示的方式却与之大不相同,很多时候...

    Unicode 和 UTF-8、UTF-16、UTF-32之间的关系

    要厘清它们之间的关系就要先从编码开始说起:

    ASCII码

    我们都知道,在计算机的世界里,信息的表示方式只有 0 和 1,但是我们人类信息表示的方式却与之大不相同,很多时候是用语言文字、图像、声音等传递信息的。
    那么我们怎样将其转化为二进制存储到计算机中,这个过程我们称之为编码。更广义地讲就是把信息从一种形式转化为另一种形式的过程。
    我们知道一个二进制有两种状态:”0” 状态 和 “1”状态,那么它就可以代表两种不同的东西,我们想赋予它什么含义,就赋予什么含义,比如说我规定,“0” 代表 “吃过了”, “1”代表 “还没吃”。
    这样,我们就相当于把现实生活中的信息编码成二进制数字了,并且这个例子中是一位二进制数字,那么 2 位二进制数可以代表多少种情况能?对,是四种,2^2,分别是 00、01、10、11,那7种呢?
    答案是2^7=128。
    我们知道,在计算机中每八个二进制位组成了一个字节(Byte),计算机存储的最小单位就是字节,字节如下图所示 :

    在这里插入图片描述
    所以早期人们用 8 位二进制来编码英文字母(最前面的一位是 0),也就是说,将英文字母和一些常用的字符和这 128 中二进制 0、1 串一一对应起来,比如说 大写字母“A”所对应的二进制位“01000001”,转换为十六进制为 41。
    在美国,这 128 是够了,但是其他国家不答应啊,他们的字符和英文是有出入的,比如在法语中在字母上有注音符号,如 é ,这个怎么表示成二进制?
    所以各个国家就决定把字节中最前面未使用的那一个位拿来使用,原来的 128 种状态就变成了 256 种状态,比如 é 就被编码成 130(二进制的 10000010)。
    为了保持与 ASCII 码的兼容性,一般最高位为 0 时和原来的 ASCII 码相同,最高位为 1 的时候,各个国家自己给后面的位 (1xxx xxxx) 赋予他们国家的字符意义。
    但是这样一来又有问题出现了,不同国家对新增的 128 个数字赋予了不同的含义,比如说 130 在法语中代表了 é,但是在希伯来语中却代表了字母 Gimel(这不是希伯来字母,只是读音翻译成英文的形式)具体的希伯来字母 Gimel 看下图
    在这里插入图片描述
    所以这就成了不同国家有不同国家的编码方式,所以如果给你一串二进制数,你想要解码,就必须知道它的编码方式,不然就会出现我们有时候看到的乱码 。

    Unicode的出现

    Unicode 为世界上所有字符都分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF (十六进制),有 110 多万,每个字符都有一个唯一的 Unicode 编号,这个编号一般写成 16 进制,在前面加上 U+。例如:“马”的 Unicode 是U+9A6C。
    Unicode 就相当于一张表,建立了字符与编号之间的联系。
    在这里插入图片描述
    它是一种规定,Unicode 本身只规定了每个字符的数字编号是多少,并没有规定这个编号如何存储。
    有的人会说了,那我可以直接把 Unicode 编号直接转换成二进制进行存储,是的,你可以,但是这个就需要人为的规定了,而 Unicode 并没有说这样弄,因为除了你这种直接转换成二进制的方案外,还有其他方案,接下来我们会逐一看到。
    编号怎么对应到二进制表示呢?有多种方案:主要有 UTF-8,UTF-16,UTF-32。

    1、UTF-32

    这个就是字符所对应编号的整数二进制形式,四个字节。这个就是直接转换。 比如马的 Unicode 为:U+9A6C,那么直接转化为二进制,它的表示就为:1001 1010 0110 1100。
    这里需要说明的是,转换成二进制后计算机存储的问题,我们知道,计算机在存储器中排列字节有两种方式:大端法和小端法,大端法就是将高位字节放到低地址处,比如 0x1234, 计算机用两个字节存储,一个是高位字节 0x12,一个是低位字节 0x34,它的存储方式为下:
    在这里插入图片描述
    UTF-32 用四个字节表示,处理单元为四个字节(一次拿到四个字节进行处理),如果不分大小端的话,那么就会出现解读错误,比如我们一次要处理四个字节 12 34 56 78,这四个字节是表示 0x12 34 56 78 还是表示 0x78 56 34 12?不同的解释最终表示的值不一样。
    我们可以根据他们高低字节的存储位置来判断他们所代表的含义,所以在编码方式中有 UTF-32BE 和 UTF-32LE,分别对应大端和小端,来正确地解释多个字节(这里是四个字节)的含义。

    2、UTF-16

    UTF-16 使用变长字节表示
    ① 对于编号在 U+0000 到 U+FFFF 的字符(常用字符集),直接用两个字节表示。
    ② 编号在 U+10000 到 U+10FFFF 之间的字符,需要用四个字节表示。
    同样,UTF-16 也有字节的顺序问题(大小端),所以就有 UTF-16BE 表示大端,UTF-16LE 表示小端。

    3、UTF-8

    UTF-8 就是使用变长字节表示,顾名思义,就是使用的字节数可变,这个变化是根据 Unicode 编号的大小有关,编号小的使用的字节就少,编号大的使用的字节就多。使用的字节个数从 1 到 4 个不等。
    UTF-8 的编码规则是:

    ① 对于单字节的符号,字节的第一位设为 0,后面的7位为这个符号的 Unicode 码,因此对于英文字母,UTF-8 编码和 ASCII 码是相同的。

    ② 对于n字节的符号 (n>1),第一个字节的前 n 位都设为 1,第 n+1 位设为 0,后面字节的前两位一律设为 10,剩下的没有提及的二进制位,全部为这个符号的 Unicode 码 。

    举个例子:比如说一个字符的 Unicode 编码是 130,显然按照 UTF-8 的规则一个字节是表示不了它(因为如果是一个字节的话前面的一位必须是 0),所以需要两个字节(n = 2)。
    根据规则,第一个字节的前 2 位都设为 1,第 3(2+1) 位设为 0,则第一个字节为:110X XXXX,后面字节的前两位一律设为 10,后面只剩下一个字节,所以后面的字节为:10XX XXXX。
    所以它的格式为 110XXXXX 10XXXXXX 。

    下面我们来具体看看具体的 Unicode 编号范围对应的 UTF-8 二进制格式
    在这里插入图片描述
    那么对于一个具体的 Unicode 编号,具体怎么进行 UTF-8 的编码呢?
    首先找到该 Unicode 编号所在的编号范围,进而可以找到与之对应的二进制格式,然后将该 Unicode 编号转化为二进制数(去掉高位的 0),最后将该二进制数从右向左依次填入二进制格式的 X 中,如果还有 X 未填,则设为 0 。
    比如:“马”的 Unicode 编号是:0x9A6C,整数编号是 39532,对应第三个范围(2048 - 65535),其格式为:1110XXXX 10XXXXXX 10XXXXXX,39532 对应的二进制是 1001 1010 0110 1100,将二进制填入进去就为:
    11101001 10101001 10101100 。

    在这里插入图片描述
    在这里插入图片描述
    由于 UTF-8 的处理单元为一个字节(也就是一次处理一个字节),所以处理器在处理的时候就不需要考虑这一个字节的存储是在高位还是在低位,直接拿到这个字节进行处理就行了,因为大小端是针对大于一个字节的数的存储问题而言的。

    综上所述,UTF-8、UTF-16、UTF-32 都是 Unicode 的一种实现。

    展开全文
  • Unicode、UTF-8UTF-16之间的区别

    万次阅读 多人点赞 2018-08-29 14:51:24
     于是UTF-8和UTF-16的优劣很容易就看出来了.如果全部英文或英文与其他文字混合,但英文占绝大部分,用UTF-8就比UTF-16节省了很多空间.而如果全部是中文这样类似的字符或者混合字符中中文占绝大多数.UTF-16就占优势了,...

    为啥需要Unicode

     

          我们知道计算机其实挺笨的,它只认识0101这样的字符串,当然了我们看这样的01串时肯定会比较头晕的,所以很多时候为了描述简单都用十进制,十六进制,八进制表示.实际上都是等价的,没啥太多不一样.其他啥文字图片之类的其他东东计算机不认识.那为了在计算机上表示这些信息就必须转换成一些数字.你肯定不能想怎么转换就怎么转,必须得有定些规则.于是刚开始的时候就有ASCII字符集(American Standard Code for Information Interchange, "美国信息交换标准码),它使用7 bits来表示一个字符,总共表示128个字符,我们一般都是用字节(byte,即8个01串)来作为基本单位.那么怎么当用一个字节来表示字符时第一个bit总是0,剩下的七个字节就来表示实际内容.后来IBM公司在此基础上进行了扩展,用8bit来表示一个字符,总共可以表示256个字符.也就是当第一个bit是0时仍表示之前那些常用的字符.当为1时就表示其他补充的字符.

            英文字母再加一些其他标点字符之类的也不会超过256个.一个字节表示主足够了.但其他一些文字不止这么多 ,像汉字就上万个.于是又出现了其他各种字符集.这样不同的字符集交换数据时就有问题了.可能你用某个数字表示字符A,但另外的字符集又是用另外一个数字表示A.这样交互起来就麻烦了.于是就出现了Unicode和ISO这样的组织来统一制定一个标准,任何一个字符只对应一个确定的数字.ISO取的名字叫UCS(Universal Character Set),Unicode取的名字就叫unicode了.

          总结起来为啥需要Unicodey就是为了适应全球化的发展,便于不同语言之间的兼容交互,而ASCII不再能胜任此任务了.

     

    Unicode详细介绍

     

    1.容易产生后歧义的两字节

            unicode的第一个版本是用两个字节(16bit)来表示所有字符

            .实际上这么说容易让人产生歧义,我们总觉得两个字节就代表保存在计算机中时是两个字节.于是任何字符如果用unicode表示的话保存下来都占两个字节.其实这种说法是错误的.

         其实Unicode涉及到两个步骤,首先是定义一个规范,给所有的字符指定一个唯一对应的数字,这完全是数学问题,可以跟计算机没半毛钱关系.第二步才是怎么把字符对应的数字保存在计算机中,这才涉及到实际在计算机中占多少字节空间.

         所以我们也可以这样理解,Unicode是用0至65535之间的数字来表示所有字符.其中0至127这128个数字表示的字符仍然跟ASCII完全一样.65536是2的16次方.这是第一步.第二步就是怎么把0至65535这些数字转化成01串保存到计算机中.这肯定就有不同的保存方式了.于是出现了UTF(unicode transformation format),有UTF-8,UTF-16.

     

    2.UTF-8 与UTF-16的区别

        UTF-16比较好理解,就是任何字符对应的数字都用两个字节来保存.我们通常对Unicode的误解就是把Unicode与UTF-16等同了.但是很显然如果都是英文字母这做有点浪费.明明用一个字节能表示一个字符为啥整两个啊.

       于是又有个UTF-8,这里的8非常容易误导人,8不是指一个字节,难道一个字节表示一个字符?实际上不是.当用UTF-8时表示一个字符是可变的,有可能是用一个字节表示一个字符,也可能是两个,三个..反正是根据字符对应的数字大小来确定.

       于是UTF-8和UTF-16的优劣很容易就看出来了.如果全部英文或英文与其他文字混合,但英文占绝大部分,用UTF-8就比UTF-16节省了很多空间.而如果全部是中文这样类似的字符或者混合字符中中文占绝大多数.UTF-16就占优势了,可以节省很多空间.另外还有个容错问题,等会再讲

     

      看的有点晕了吧,举个例子.假如中文字"汉"对应的unicode是6C49(这是用十六进制表示,用十进制表示是27721为啥不用十进制表示呢?很明显用十六进制表示要短点.其实都是等价的没啥不一样.就跟你说60分钟和1小时一样.).你可能会问当用程序打开一个文件时我们怎么知道那是用的UTF-8还是UTF-16啊.自然会有点啥标志,在文件的开头几个字节就是标志.

    EF BB BF 表示UTF-8

    FE FF 表示UTF-16.

     

    用UTF-16表示"汉"

    假如用UTF-16表示的话就是01101100   01001001(共16 bit,两个字节).程序解析的时候知道是UTF-16就把两个字节当成一个单元来解析.这个很简单.

    用UTF-8表示"汉"

    用UTF-8就有复杂点.因为此时程序是把一个字节一个字节的来读取,然后再根据字节中开头的bit标志来识别是该把1个还是两个或三个字节做为一个单元来处理.

    0xxxxxxx,如果是这样的01串,也就是以0开头后面是啥就不用管了XX代表任意bit.就表示把一个字节做为一个单元.就跟ASCII完全一样.

    110xxxxx 10xxxxxx.如果是这样的格式,则把两个字节当一个单元

    1110xxxx 10xxxxxx 10xxxxxx 如果是这种格式则是三个字节当一个单元.

    这是约定的规则.你用UTF-8来表示时必须遵守这样的规则.我们知道UTF-16不需要用啥字符来做标志,所以两字节也就是2的16次能表示65536个字符.

    而UTF-8由于里面有额外的标志信息,所有一个字节只能表示2的7次方128个字符,两个字节只能表示2的11次方2048个字符.而三个字节能表示2的16次方,65536个字符.

    由于"汉"的编码27721大于2048了所有两个字节还不够,只能用三个字节来表示.

    所有要用1110xxxx 10xxxxxx 10xxxxxx这种格式.把27721对应的二进制从左到右填充XXX符号(实际上不一定从左到右,也可以从右到左,这是涉及到另外一个问题.等会说.

    刚说到填充方式可以不一样,于是就出现了Big-Endian,Little-Endian的术语.Big-Endian就是从左到右,Little-Endian是从右到左.

    由上面我们可以看出UTF-8在局部的字节错误(丢失、增加、改变)不会导致连锁性的错误,因为 UTF-8 的字符边界很容易检测出来,所以容错性较高。

     

    Unicode版本2

        前面说的都是unicode的第一个版本.但65536显然不算太多的数字,用它来表示常用的字符是没一点问题.足够了,但如果加上很多特殊的就也不够了.于是从1996年开始又来了第二个版本.用四个字节表示所有字符.这样就出现了UTF-8,UTF16,UTF-32.原理和之前肯定是完全一样的,UTF-32就是把所有的字符都用32bit也就是4个字节来表示.然后UTF-8,UTF-16就视情况而定了.UTF-8可以选择1至8个字节中的任一个来表示.而UTF-16只能是选两字节或四字节..由于unicode版本2的原理完全是一样的,就不多说了.

    前面说了要知道具体是哪种编码方式,需要判断文本开头的标志,下面是所有编码对应的开头标志

    EF BB BF    UTF-8
    FE FF     UTF-16/UCS-2, little endian
    FF FE     UTF-16/UCS-2, big endian
    FF FE 00 00  UTF-32/UCS-4, little endian.
    00 00 FE FF  UTF-32/UCS-4, big-endian.

    其中的UCS就是前面说的ISO制定的标准,和Unicode是完全一样的,只不过名字不一样.ucs-2对应utf-16,ucs-4对应UTF-32.UTF-8是没有对应的UCS


    UTF-16 并不是一个完美的选择,它存在几个方面的问题:

    1. UTF-16 能表示的字符数有 6 万多,看起来很多,但是实际上目前 Unicode 5.0 收录的字符已经达到 99024 个字符,早已超过 UTF-16 的存储范围;这直接导致 UTF-16 地位颇为尴尬——如果谁还在想着只要使用 UTF-16 就可以高枕无忧的话,恐怕要失望了
    2. UTF-16 存在大小端字节序问题,这个问题在进行信息交换时特别突出——如果字节序未协商好,将导致乱码;如果协商好,但是双方一个采用大端一个采用小端,则必然有一方要进行大小端转换,性能损失不可避免(大小端问题其实不像看起来那么简单,有时会涉及硬件、操作系统、上层软件多个层次,可能会进行多次转换)
    3. 另外,容错性低有时候也是一大问题——局部的字节错误,特别是丢失或增加可能导致所有后续字符全部错乱,错乱后要想恢复,可能很简单,也可能会非常困难。(这一点在日常生活里大家感觉似乎无关紧要,但是在很多特殊环境下却是巨大的缺陷)

    目前支撑我们继续使用 UTF-16 的理由主要是考虑到它是双字节的,在计算字符串长度、执行索引操作时速度很快。当然这些优点 UTF-32 都具有,但很多人毕竟还是觉得 UTF-32 太占空间了。

    反过来 UTF-8 也不完美,也存在一些问题:

    1. 文化上的不平衡——对于欧美地区一些以英语为母语的国家 UTF-8 简直是太棒了,因为它和 ASCII 一样,一个字符只占一个字节,没有任何额外的存储负担;但是对于中日韩等国家来说,UTF-8 实在是太冗余,一个字符竟然要占用 3 个字节,存储和传输的效率不但没有提升,反而下降了。所以欧美人民常常毫不犹豫的采用 UTF-8,而我们却老是要犹豫一会儿
    2. 变长字节表示带来的效率问题——大家对 UTF-8 疑虑重重的一个问题就是在于其因为是变长字节表示,因此无论是计算字符数,还是执行索引操作效率都不高。为了解决这个问题,常常会考虑把 UTF-8 先转换为 UTF-16 或者 UTF-32 后再操作,操作完毕后再转换回去。而这显然是一种性能负担。



    当然,UTF-8 的优点也不能忘了:

    1. 字符空间足够大,未来 Unicode 新标准收录更多字符,UTF-8 也能妥妥的兼容,因此不会再出现 UTF-16 那样的尴尬
    2. 不存在大小端字节序问题,信息交换时非常便捷
    3. 容错性高,局部的字节错误(丢失、增加、改变)不会导致连锁性的错误,因为 UTF-8 的字符边界很容易检测出来,这是一个巨大的优点(正是为了实现这一点,咱们中日韩人民不得不忍受 3 字节 1 个字符的苦日子)


    那么到底该如何选择呢?

    因为无论是 UTF-8 和 UTF-16/32 都各有优缺点,因此选择的时候应当立足于实际的应用场景。例如在我的习惯中,存储在磁盘上或进行网络交换时都会采用 UTF-8,而在程序内部进行处理时则转换为 UTF-16/32。对于大多数简单的程序来说,这样做既可以保证信息交换时容易实现相互兼容,同时在内部处理时会比较简单,性能也还算不错。(基本上只要你的程序不是 I/O 密集型的都可以这么干,当然这只是我粗浅的认识范围内的经验,很可能会被无情的反驳)

    稍微再展开那么一点点……

    在一些特殊的领域,字符编码的选择会成为一个很关键的问题。特别是一些高性能网络处理程序里更是如此。这时采用一些特殊的设计技巧,可以缓解性能和字符集选择之间的矛盾。例如对于内容检测/过滤系统,需要面对任何可能的字符编码,这时如果还采用把各种不同的编码都转换为同一种编码后再处理的方案,那么性能下降将会很显著。而如果采用多字符编码支持的有限状态机方案,则既能够无需转换编码,同时又能够以极高的性能进行处理。当然如何从规则列表生成有限状态机,如何使得有限状态机支持多编码,以及这将带来哪些限制,已经又成了另外的问题了。

     

     

    转自:https://www.cnblogs.com/fnlingnzb-learner/p/6163205.html

    展开全文
  • 字符编码的概念(UTF-8UTF-16、UTF-32都是什么鬼)

    万次阅读 多人点赞 2017-11-30 17:11:56
    UTF-16:介于 UTF-8 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变。 UTF 是 Unicode Transformation Format 的缩写,意思是“Unicode转换格式”,后面的数字表明至少使用多少个比特位(Bit)来...

    字符集为每个字符分配了一个唯一的编号,通过这个编号就能找到对应的字符。在编程过程中我们经常会使用字符,而使用字符的前提就是把字符放入内存中,毫无疑问,放入内存中的仅仅是字符的编号,而不是真正的字符实体。

     

    这就抛出了一个问题,如何才能将字符编号放入内存中呢?

     

    对于 ASCII 字符集,这很容易。ASCII 总共包含 128 个字符,用 7 个比特位(Bit)恰好能够存储,不过考虑到计算机一般把字节(Byte)作为基本单元,为了操作方便,我们不妨用一个字节(也就是 8 个比特位)来存储 ASCII。这样虽然浪费了一个比特位,但是读写效率提高了。

     

    但是对于 Unicode,问题就没有这么简单了。Unicode 目前已经包含了上百万的字符,位置靠前的字符用一个字节就能存储,位置靠后的字符用三个字节才能存储。我们可以为所有字符都分配三个字节的内存,也可以为编号小的字符分配一个字节或者两个字节的内存,而为编号大的字符分配三个字节的内存。

     

    这两种方案各有优缺点,请读者看下面的分析。

    字符集和字符编码不是一个概念,字符集定义了文字和二进制的对应关系,为字符分配了唯一的编号,而字符编码规定了如何将文字的编号存储到内存中。有的字符集在制定时就考虑到了编码的问题,是和编码结合在一起的;有的字符集只管制定字符的编号,至于怎么编码,是其他人的事情。

    方案1:为每个字符分配固定长度的内存

    一种方案是为每个字符分配固定长度的内存,并且这块内存要足够大,可以容纳下所有的字符编号。这种方案最简单,直接将字符编号放入内存中即可,不需要任何转换,并且以后在字符串中定位字符、修改字符都非常容易。

    字符串就是一串连续的字符序列,它们在内存中按次序挨着存放。在C语言中,字符串由双引号 " "包围起来。

    目前的 Unicode 已经收录了上百万的字符,至少需要三个字节才能容纳下所有的字符编号。假设字符串"A3中¥"的 Unicode 编码值(十六进制形式)分别是 2A、31、DA49、BB672C,那么它们在内存中的存储形式为:

     

    在几乎所有的字符集中,常用字符的编号往往比较小,罕见字符的编号往往比较大,包括 Unicode 在内。

     

    A和3是 ASCII 编码中的字符,Unicode 为了兼容 ASCII,在设计时刻意保留了原来 ASCII 中字符的编号,所以英文字母和阿拉伯数字在 Unicode 中的编号都非常小,用一个字节足以容纳。中是一个汉字,编号比较大,一般要用两个字节才能容纳。¥可以看做是一个极其少见,或者只有极少数地区才会使用到的字符,这样的字符编号往往比较大,有时候需要三个字节才能容纳。

    是人民币符号,是汉字文化的一部分,它和其它汉字一样,实际上是用两个字节存储的,不过这里我们为了演示,故意犯错地说它需要三个字节。

    上图中带灰色背景的字节是没有用到的字节,它们就是被浪费掉的一部分内存空间,这就是用固定长度的内存来存储字符编号的缺点:常用字符的编号都比较小,这种方案会浪费很多内存空间,对于以英文为主的国家,比如美国、加拿大、英国等,内存利用率甚至会低于 50%。

    方案2:为每个字符分配尽量少的内存

    既然上面的方案有缺点,那我们就来改进一下。改进的思路也很明确,就是把空闲的内存压缩掉,为每个字符分配尽量少的字节,例如,A和3分配一个字节足以,中分配两个字节足以,如下图所示:

    这样虽然没有了空闲字节,不浪费任何内存空间了,但是又出现新的问题了:如果我不告诉你,你怎么知道2A表示一个字符,而不是2A31或者2A31DA才表示一个字符呢?后面的字符也有类似的问题。

     

    对于第一种方案,每个字符占用的字节数是固定的,很容易区分各个字符;而这种方案,不同的字符占用的字节数不同,字符之间也没有特殊的标记,计算机是无法定位字符的。

     

    这种方案还需要改进,必须让不同的字符编码有不同的特征,并且字符处理程序也需要调整,要根据这些特征去识别不同的字符。

     

    要想让不同的字符编码有不同的特征,可以从两个方面下手:

    1) 一是从字符集本身下手,在设计字符集时,刻意让不同的字符编号有不同的特征。

     

    例如,对于编号较小的、用一个字节足以容纳的字符,我们就可以规定这个字符编号的最高位(Bit)必须是 0;对于编号较大的、要用两个字节存储的字符,我们就可以规定这个字符编号的高字节的最高位必须是 1,低字节的最高位必须是 0;对于编号更大的、需要三个字节存储的字符,我们就可以规定这个字符编号的所有字节的最高位都必须是 1。

     

    程序在定位字符时,从前往后依次扫描,如果发现当前字节的最高位是 0,那么就把这一个字节作为一个字符编号。如果发现当前字节的最高位是 1,那么就继续往后扫描,如果后续字节的最高位是 0,那么就把这两个字节作为一个字符编号;如果后续字节的最高位是 1,那么就把挨着的三个字节作为一个字符编号。

     

    这种方案的缺点很明显,它会导致字符集不连续,中间留出大量空白区域,这些空白区域不能定义任何字符。

     

    2) 二是从字符编号下手,可以设计一种转换方案,字符编号在存储之前先转换为有特征的、容易定位的编号,读取时再按照相反的过程转换成字符本来的编号。

     

    那么,转换后的编号要具备什么样的特征呢?其实也可以像上面一样,根据字节的最高位是 0 还是 1 来判断字符到底占用了几个字节。

     

    相比第一种方案,这种方案有缺点也有优点:

     

    • 缺点就是多了转换过程,字符在存储和读取时要经过转换,效率低;
    • 优点就是在制定字符集时不用考虑存储的问题,可以任意排布字符。

     

    Unicode 到底使用哪种编码方案

    Unicode 是一个独立的字符集,它并不是和编码绑定的,你可以采用第一种方案,为每个字符分配固定长度的内存,也可以采用第二种方案,为每个字符分配尽量少的内存。

     

    需要注意的是,Unicode 只是一个字符集,在制定的时候并没有考虑编码的问题,所以采用第二种方案时,就不能从字符集本身下手了,只能从字符编号下手,这样在存储和读取时都要进行适当的转换。

     

    Unicode 可以使用的编码有三种,分别是:

    • UFT-8:一种变长的编码方案,使用 1~6 个字节来存储;
    • UFT-32:一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储;
    • UTF-16:介于 UTF-8 和 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变。

     

    UTF 是 Unicode Transformation Format 的缩写,意思是“Unicode转换格式”,后面的数字表明至少使用多少个比特位(Bit)来存储字符。

    1) UTF-8

    UTF-8 的编码规则很简单:如果只有一个字节,那么最高的比特位为 0;如果有多个字节,那么第一个字节从最高位开始,连续有几个比特位的值为 1,就使用几个字节编码,剩下的字节均以 10 开头。

     

    具体的表现形式为:

    • 0xxxxxxx:单字节编码形式,这和 ASCII 编码完全一样,因此 UTF-8 是兼容 ASCII 的;
    • 110xxxxx 10xxxxxx:双字节编码形式;
    • 1110xxxx 10xxxxxx 10xxxxxx:三字节编码形式;
    • 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx:四字节编码形式。

     

    xxx 就用来存储 Unicode 中的字符编号。

     

    下面是一些字符的编码实例(绿色部分表示本来的 Unicode 编号):

     

    字符Næ
    Unicode 编号(二进制)010011101110011000101110 11101100
    Unicode 编号(十六进制)4EE62E EC
    UTF-8 编码(二进制)0100111011000011 1010011011100010 10111011 10101100
    UTF-8 编码(十六进制)4EC3 A6E2 BB AC

    对于常用的字符,它的 Unicode 编号范围是 0 ~ FFFF,用 1~3 个字节足以存储,只有及其罕见,或者只有少数地区使用的字符才需要 4~6个字节存储。

    2) UTF-32

    UTF-32 是固定长度的编码,始终占用 4 个字节,足以容纳所有的 Unicode 字符,所以直接存储 Unicode 编号即可,不需要任何编码转换。浪费了空间,提高了效率。

    3) UTF-16

    UFT-16 比较奇葩,它使用 2 个或者 4 个字节来存储。

     

    对于 Unicode 编号范围在 0 ~ FFFF 之间的字符,UTF-16 使用两个字节存储,并且直接存储 Unicode 编号,不用进行编码转换,这跟 UTF-32 非常类似。

     

    对于 Unicode 编号范围在 10000~10FFFF 之间的字符,UTF-16 使用四个字节存储,具体来说就是:将字符编号的所有比特位分成两部分,较高的一些比特位用一个值介于 D800~DBFF 之间的双字节存储,较低的一些比特位(剩下的比特位)用一个值介于 DC00~DFFF 之间的双字节存储。

     

    如果你不理解什么意思,请看下面的表格:

     

    Unicode 编号范围
    (十六进制)
    具体的 Unicode 编号
    (二进制)
    UTF-16 编码编码后的
    字节数
    0000 0000 ~ 0000 FFFFxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx2
    0001 0000---0010 FFFFyyyy yyyy yyxx xxxx xxxx110110yy yyyyyyyy 110111xx xxxxxxxx4

     

    位于 D800~0xDFFF 之间的 Unicode 编码是特别为四字节的 UTF-16 编码预留的,所以不应该在这个范围内指定任何字符。如果你真的去查看 Unicode 字符集,会发现这个区间内确实没有收录任何字符。

     

     

    UTF-16 要求在制定 Unicode 字符集时必须考虑到编码问题,所以真正的 Unicode 字符集也不是随意编排字符的。

    总结

    只有 UTF-8 兼容 ASCII,UTF-32 和 UTF-16 都不兼容 ASCII,因为它们没有单字节编码。

     

    如果你希望查看完整的 Unicode 字符集,以及各种编码方式,请猛击:https://unicode-table.com/cn/

    虽然这个网站有时候无法访问,但它是最好的一个查看 Unicode 字符集的网站。

    GB2312、Shift-JIS 等国家(地区)字符集怎么编码

    GB2312、GBK、Shift-JIS 等特定国家的字符集都是在 ASCII 的基础上发展起来的,它们都兼容 ASCII,所以只能采用变长的编码方案:用一个字节存储 ASCII 字符,用多个字节存储本国字符。

     

    以 GB2312 为例,该字符集收录的字符较少,所以使用 1~2 个字节编码。

    • 对于 ASCII 字符,使用一个字节存储,并且该字节的最高位是 0;
    • 对于中国的字符,使用两个字节存储,并且规定每个字节的最高位都是 1。

     

     

    由于单字节和双字节的最高位不一样,所以很容易区分一个字符到底用了几个字节。

    宽字符和窄字符(多字节字符)

    有的编码方式采用 1~n 个字节存储,是变长的,例如 UTF-8、GB2312、GBK 等;如果一个字符使用了这种编码方式,我们就将它称为多字节字符,或者窄字符。

     

    有的编码方式是固定长度的,不管字符编号大小,始终采用 n 个字节存储,例如 UTF-32、UTF-16 等;如果一个字符使用了这种编码方式,我们就将它称为宽字符。

     

    Unicode 字符集可以使用窄字符的方式存储,也可以使用宽字符的方式存储;GB2312、GBK、Shift-JIS 等国家编码一般都使用窄字符的方式存储;ASCII 只有一个字节,无所谓窄字符和宽字符。

    展开全文
  • 我们知道计算机是二进制的方式存储数据,要想将人类世界的文字符号存储到计算机,就需要将数据”翻译”成计算机语言进行存储,显示的时候又”翻译”成人类可识的数据,那么中间是翻译的过程需要的”字典”就是编码表,...

    简介

    在编程中经常会遇到的编码问题,例如乱码问题或者文本显示成??的形式.我们知道计算机是二进制的方式存储数据,要想将人类世界的文字和符号存储到计算机,就需要将数据”翻译”成计算机语言进行存储,显示的时候又”翻译”成人类可识的数据,那么中间是翻译的过程需要的”字典”就是编码表,也就是将计算机二进制和文字、符号映射.计算机中存储信息的最小单元是字节(byte),一个字节有8个二进制位(bit),每个二进制只有两种状态,0或者1表示.那么8个二进制位就是2的8次幂,结果是256种状态,二进制范围是从0000000011111111.

    ASCII码

    起初美国有关标准组织制定了一套编码叫ASCII码,用了一个字节低7位,最高位二进制位0,编码范围是00000000-0xxxxxxx,总共有128状态,表示了大小写字母,数字,标点符号以及特殊的控制字符.

    0~31以及127(共33个)是控制字符,例如:LF(换行),CR(回车).

    32~126(共95个)是字符,48~57为0到9共十个阿拉伯数字,65~122是大小的英文字母,其余的是字符,运算符等.

    所以ACSII码编码的格式是0xxxxxxx.一个字节中除了ASCII编码外,剩余的位置还有128个状态,对于一些西欧国家,文字比较少,这些编码位置已经够用,但是对于汉字个数远多余128个,所以出现了其他编码方式.

    ISO8859-1

    别名是Latin1,Iso-8859-1编码是属于单字节的编码,即编码的范围是0到255.总共能表示256个字符,向下兼容了ACSII,也就是在ASCII编码的基础上扩展了127-255之间位置。编码范围是0x00-0xFF,涵盖了部分西欧的语言字符.由于和计算机的存储单元一样,应用比较广泛,例如在网络传输协议中和Mysql数据库默认的编码

    GB2312

    GB2312是中国国家标准总局在1980年发布,用于汉字处理,汉字通信等系统之间信息,主要编码的字符是简化汉字,以及常用字母和符号,中国大陆地区和新加坡等地广泛使用.总共收录字符有7445个,其中简化的汉字是6763,以及包含拉丁字母,希腊字母,日文平假名及片假名字母,俄语西里尔字母在内的全角字符有682个.

    GB2312对收录的字符进行了分区处理,共有94个区,每个区有94个字符,这种表示字符的方式叫区位码.例如下面01区和02区. 

    每个区具体的分布的字符如下:

    区号

    编码总数

    表示的符号

    01

    94

    一般符号

    02

    72

    顺序号码

    03

    94

    拉丁字母

    04

    83

    日文假名

    05

    86

    Katakana

    06

    48

    希腊字母

    07

    66

    俄文字母

    08

    63

    汉语拼音符号

    09

    76

    图形符号

    10-15

    0

    没有编码

    16-55

    3755

    一级汉字,以拼音为序

    56-87

    3008

    二级汉字,以笔划为序

    88-94

    0

    没有编码

         GB2312编码以两个字节来表示汉字和符号,第一个字节是区码,第二个字节是位码.由于GB2312编码覆盖了ACSII编码中字母和符号的编码,对于ASCII中的32个控制字符继续沿用,所以需要将编码移动十六进制20H(32)得到国标码,在计算机的存储中,使用GB2312编码和ASCII编码会出现冲突的情况,比如说,国标码是20H83H,但是ASCII编码中表示成字符是控制符”DC4”20H)和大写字母”S”(80H).如果遇到编码是2083H,解码成是汉字还是字符。容易引起歧义, 解决方式就是在计算机里面存储变形国标码,将区码和位码分别加上128,即每个字节的最高位将0改为1.

    那么对于区位码.国标码和机内码转换的方式:

    1. 区位码(十六进制)+20 20H=国标码
    2. 国标码+80 80H=机内码

    区位码转换成机内码,也可以直接区位码(十六进制)+A0A0H=机内码,

    20208080等同A0A0的原因是20(十六进制)的十进制是32,80(十六进制)的十进制是128,32+128=160(十进制)->A0(十六进制).

    也就是说GB2312编码是以2个字节进行存储的,存到到计算机里面的编码就是将GB2312区位码+A0 A0H=存储码(即机内码),此外计算机存储规则是此编码的补码,注意的是位码在前,区码在后面

    GBK/GBK18030

    GBK字符集是GB2312的扩展,兼容了GB2312字符编码,共包含了21886个字符,GBK也支持希腊字母,日文假名字母,俄语字母等.

    GB18030编码向下兼容了GBKGB2312.GB18030收录了所有的Unicode3.1中的字符,包含中国少数民族的字符.编码方式变长编码,有单字节.双字节和四字节三种方式.GB18030的单字节编码范围是0x00-0x7F,完全等同于ASCII码;双字节编码的范围和GBK相同,高字节是0x81-0xFE,低字节的编 码范围是0x40-0x7E0x80-FE;四字节编码中第一、三字节的编码范围是0x81-0xFE,二、四字节是0x30-0x39

    Unicode

         由于多种编码方式的存在,同一个二进制编码可以解释成不同的符号,解码如果和解码方式不要一致,可能出现乱码的情况。解决这种问题方式就是Unicode编码,Unicode是很大的字符集,可以理解成一部全世界上所有的文字和字符与数字对应的字典”, 容纳的字符达到了100多万,每一个字符对应一个数字,但对于具体怎么存储到计算机中没有任何规定.如果将Unicode编码存直接储到计算里面会有什么结果呢?例如汉字”,Unicode编码是0x4e2d,二进制是100111000101101,二进制数有15位,也就是最少要用两个字节表示.可以想象Unicode字符集越往后面的字符编码,需要三到四个字节,甚至更多的字节来存储.如果按照固定字节来存储,那么就需要按照数值最大的字符所需要的字节为标准,例如规定四个字节表示一个字符,那么像英文字母仅仅只需一个字节可以表示的字符(如字母”b”,二进制是1100010,只需要一个字节可表示),依旧需要四个字节表示,就会造成极大的空间浪费.

    为了解决Unicode字符集在电脑中存储问题,出现了UTF-8UTF-16.UTF-32等编码方式.

    需要注意的是UTF-8和UTF-16,UTF-32编码就是Unicode字符集存储到电脑中实现的方式,

    UTF-8

     UTF-8编码是Unicode字符集一种编码方式,被广泛使用.特点是使用变长的字节数来存储数据, 一般都是14个字节,变长的方式指的是将Unicode编码按照规则进行编码,比如一个字节可表示所有的ASCII字符,就不需要用两个字节.

    按照UTF-8编码规则,就是将Unicode字符集按照满足UTF-8编码规则存储,解码按照UTF-8编码规则进行解码.如下:

    UTF-8占用字节数

    Unicode 十六进制编码范围

    UTF-8二进制编码方式

    1个字节

    0000 0000 - 0000 007F

    0xxxxxxx

    2个字节

    0000 0080 - 0000 07FF

    110xxxxx 10xxxxxx

    3个字节

    0000 0800 - 0000 FFFF

    1110xxxx 10xxxxxx 10xxxxxx

    4个字节

    0001 0000 - 0010 FFFF

    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

    比如汉字”,Unicode的编码是0x4e2d(100111000101101),通过上面表对照可以知道,0x4e2d在Unicode十六进制编码0000 0800-0000 FFFF范围之间,那么UTF-8的编码方式应该时1110xxxx 10xxxxxx 10xxxxxx,填充方式就是将的二进制从后向前填充,多余的x使用0填充,那么UTF-8编码就是11100100 10111000 10101101,转换成十六进制就是E4B8AD

    解码的过程也是根据UTF-8编码规则进行解码,首字节的第一位是0,那么就是一个字节对应一个字符,首字节前两位是11,那么就是两个字节表示一个字符,即有几个1,就用几个字节表示一个字符,比如”UTF-8编码就是11100100 10111000 10101101,首字节有3个1,就表示是三个字节表示一个字符,会根据1110xxxx 10xxxxxx 10xxxxxx拿到x的部分,100111000101101,十六进制是0x4e2d,Unicode字符集对应的就是汉字”.

    变长编码的优点是节省空间,利于传输,适合字符串网络传输的编码方式。

    UTF-16(没有辅助平面字符情况下等同UCS-2编码)

     UTF-16用定长2个字节或者是两个2个字节(代理对的形式表示)来编码Unicode字符,UTF-16编码比起UTF-8字节,大部分的字符都是以固定两个字节存储,但是无法兼容ASCII编码。先对Unicode字符集的平面需要了解。

    Unicode字符集将世界上所有的文字和符号进行了编码,目前Unicode字符分成了17个组(区)来编排,总的编码范围是0x0000-0x10FFFF(十进制是1114112,即能容纳的字符这么多)。每一个组又称为一个平面,每个平面有65536个码位,即每个平面能容纳字符65536个字符。

    第一个组,又称为第零平面或者基本平面(BMP,编码范围是0x0000-0xFFFF,所有常见的文字和字符都在这个平面,其他的组或者区叫辅助平面(SMP),编码的范围是0x10000-0x10FFFFUTF-16编码的规则是:基本平面内的字符用2个字节表示,而辅助平面的字符要用4个字节表示

    在基本平面里面有个称为代理区的特殊区域,编码范围是0xD800-0xDFFF,共有2048个码位,此区间不对应任何字符,主要是用于映射辅助平面的字符。

    UTF-16占用字节数

    Unicode十六进制编码范围

    UTF-16二进制编码方式

    Unicode字符范围

    2个字节

    0x0000-0xFFFF

    xxxxxxxx xxxxxxxx

    0-65535

    4个字节

    0x10000-0x10FFFF

    110110yyyyyyyyyy 110111xxxxxxxxxx

    65536-1114111

    具体编码如下:

    • 1.Unicode编码范围是0x0000-0xFFFF,即编码<0x10000,UTF-16编码与Uncode字符的值保持一致。比如汉字“”,Unicode十六进制是0x554A,是上表中Unicode十六进制编码0x0000-0xFFFF范围,UTF-16占用两个字节,是基本平面内的字符,UTF-16编码方式是0x554A(二进制是101010101001010

    2.Unicode编码范围是0x10000-0x10FFFF,即编码>=0x10000.Unicode编码值是U,计算编码值=U-0x10000转换成二进制就是yyyyyyyyyy xxxxxxxxxx,其中二进制位不存在的补0.那么UTF-16编码就是110110yyyyyyyyyy 110111xxxxxxxxxx.

    UTF-164个字节编码方式看,第一个2个字节,即110110yyyyyyyyyy,取值范围是1101100000000000-1101101111111111,转换成十六进制就是0xD800-0xDBFF,此区间称为高位替代。

    对于Unicode编码范围大于0x10000的字符。第二个2个字节是110111xxxxxxxxxx,取值范围是1101110000000000-1101111111111111,转换成十六机制就是0xDC00-0xDFFF。此区间称为低位替代。

    0xD800-0xDBFF

    高位替代

    0xDC00-0xDFFF

    低位替代

          可以看到Unicode字符集中>0x10000的字符,也就是辅助平面内的字符,通过UTF-16编码规则将每两个字节映射到0xD800-0xDBFF之间,所以当一篇文档使用UTF-16编码,两个字节编码范围是0xD800-0xDBFF之间,说明解码需要前后四个字节才能解码出一个完整字符。

    例如:汉字“

    展开全文
  • (Unicode) UTF-8UTF-16之间转换

    万次阅读 2016-10-21 13:33:39
    在保存时就涉及到了在计算机中占多少字节空间,就有不同的保存方式,于是出现了UTF(unicode transformation format):UTF-8和UTF-16。 三、UTF-8和UTF-16的区别    1、UTF-16:是任何字符对应的数字都用两...
  • UTF-8和不带BOM的UTF-8有什么区别?

    千次阅读 2019-12-20 09:24:02
    没有BOM的 UTF-8和UTF-8有什么区别? 哪个更好?
  • C++ UTF-8 转换助手 ...这篇文章介绍如何用C++,Win32SDKSTL 实现在UTF-8和UTF-16之间进行转换。 使用技术:Win32,C++,Windows SDK,STL 主题:Unicode 介绍: 对于Unicode来说有几种不同的编码方式
  • utf-8和utf-8-sig的区别(CSV文件 乱码)

    万次阅读 多人点赞 2019-07-17 14:35:45
    1、”utf-8“ 是以字节为编码单元,它的字节顺序在所有系统中都是一样的,没有字节序问题,因此它不需要BOM,所以当用"utf-8"编码方式读取带有BOM的文件时,它会把BOM当做是文件内容来处理, 也就会发生类似上边的错误. ...
  • UTF-8, UTF-16, UTF-16LE, UTF-16BE的区别

    千次阅读 2015-06-22 20:39:39
    首先, 我们说的unicode, 其实就是utf-16, 但最通用的却是utf-8 原因: 我猜大概是英文占的比例比较大, 这样utf-8的存储优势比较明显, 因为utf-16是固定16位的(双字节), 而utf-8则是看情况而定, 即可变长度, 常规的128...
  • 原文1链接:[Charset]UTF-8, UTF-16, UTF-16LE, UTF-16BE的区别 原文2链接:UTF8,UTF16,UTF32,UTF16-LE,UTF16-BE,GBK 之间的转换 文章1 最近遇到的麻烦事  charset里的问题, 一般我们都用unicode来作为统一编码...
  • UTF-8、en_US.UTF-8和zh_CN.UTF-8的区别 en_US.UTF-8、zh_CN.UTF-8叫做字符集,就是说‘A’、‘B’、‘中’、‘国’等对应的整数值, en_US.UTF-8只包含了ASCII码,zh_CN.UTF-8包含了6000多个汉字? 如果是这样的话...
  • UTF-16UTF-8的方法,防止文件有BOM头

    千次阅读 2019-01-27 10:25:07
    在读公司代码的时候,发现了一个UTF-16UTF-8的方法,这还是博主第一次见到这种方法,不由的好奇了起来。为什么要转,应用场景是什么呢?这里大家一起来探讨下 二、贴代码 /** * @desc UTF-16转为UTF-8编码, 必须...
  • utf-8和utf-8-sig

    千次阅读 2017-11-07 12:00:26
    As UTF-8 is an 8-bit encoding no BOM is required and anyU+FEFF character in the decoded Unicode string (even if it’s the firstcharacter) is treated as a ZERO WIDTH NO-BREAK SPACE. UTF-8以字节为...
  • UTF-8和UTF-16使用对比

    千次阅读 2013-12-23 14:31:53
    UTF-16  说到 UTF 必须要提到 Unicode(Universal Code 统一码),ISO 试图想创建一个全新的超语言字典,世界上所有的语言都可以通过这本字典来相互翻译。可想而知这个字典是多么的复杂,关于 Unicode 的详细规范...
  • 1、区别编码字符集字符集编码首先要注意的是unicode是编码字符集,而UTF-8UTF-16、UTF-32是字符集编码(好绕哎有没有)。下面我来具体解释一下:比如汉字的”汉”,在unicode中,汉”的unicode值为0x6C49。问:把...
  • java编码方案为什么会产生乱码
  • UTF-8 带BOM UTF-8无BOM 的区别?

    千次阅读 2019-02-26 17:36:01
    它能够让读者更可靠的识别文件是否以UTF-8编码的。 通常,BOM用于表示编码的字节顺序, 但是由于字节顺序与UTF-8无关,因此BOM不是必须的。 根据Unicode标准,不建议使用UTF-8文件的BOM。 常见问题: 从网上下载的...
  • 从txt文件中读取一串字符串数据库中另一串字符串比较的时候发现两串字符串一样,但是判断是否equal的时候发现返回的是false,也就是不相等。这就奇怪了,于是打印log,发现了端倪: 左边的字符串是数据库的,...
  • UTF-8带BOM格式与UTF-8无BOM格式转换

    千次阅读 2019-05-16 19:56:58
    Qt在windows下使用VS建立的工程文件转到Linux环境下编译报出大量错误,...VS采用UTF-8 BOM格式编码,而Linux下采用UTF-8无BOM格式。BOM用来标记编码的字节顺序,但是由于编码字节顺序对于UTF-8来说无关紧要,而且Un...
  • python中Unicode和UTF-8的区别

    千次阅读 2020-12-01 12:40:01
    如下编写一个脚本:如果不添加#coding=utf-8,脚本有中文时程序会报错2,UnicodeUFT-8的区别Unicode 是字符集UTF-8 是编码规则字符集:为每一个「字符」分配一个唯一的 ID(学名为码位 / 码点...
  • 首先明确一点:UTF-8 BOM与UTF-8带签名指的是同一回事,二者指的是UTF-8的同一格式 UTF-8 BOM中的BOM,全称为Byte order mark。 带BOM(签名)的UTF-8文本文件与不带BOM的UTF-8文本文件的区别在于:前者在文件的...
  • 这是个标识UTF-8编码文件的好办法,软件通过BOM来识别这个文件是否是UTF-8编码,很多软件还要求读入的文件必须带BOM。可 是,还是有很多软件不能识别BOM。   在Firefox早期的版本里,扩展是不能有BOM的,不过...
  • MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf...
  • ,该编译选项的作用就是将源码字符集执行文件字符集指定为UTF-8。增加该编译选项后,再重新编译运行,程序正确输出中文,问题解决。 参见微软官网: 《/utf-8 (Set Source and Executable character sets to...
  • utf-8与带有BOM的utf-8的区别

    千次阅读 2020-06-17 08:20:14
    最近在学习处理的过程中,遇到了需要txt转换为csv文件的需求,第一步当然是另存txt为utf-8的格式,但是博主在保存时,发现了utf-8有两种格式,如下图: 怀着满满的好奇心,我查找了一下两者的区别: ...
  • 将字符串的编码格式转换为utf-8

    千次阅读 2021-02-13 00:31:13
    方式一:/*** 将字符串的编码格式转换为utf-8** @param str* @return Name = new* String(Name.getBytes("ISO-8859-1"), "utf-8");*/public static String toUTF8(String str) {if (isEmpty(str)) {return "";}try {...
  • 前言:上一篇文章写了关于Unicode,以及utf-8utf-16相关知识。所以本篇博文来验证在java环境下,字符在不同编码下所占的字计数。 测试代码如下:package string;public class CharByteTest { public static void ...
  • 批量转换文件编码格式为UTF-8工具

    千次下载 热门讨论 2012-08-02 16:44:56
    批量转换文件编码格式为UTF-8工具.zip 支持多层文件夹替换! 使用说明: 1.文件根目录:即您要转码的文件所在根目录 2.转码文件目录:即您转码后的文件所在目录 3.转码文件后缀:指[文件根目录]下,需要转码的文件后缀,...
  • utf-8utf-8-sig 两种编码格式区别

    千次阅读 2019-09-29 22:29:32
    简单讲utf-8无字序的问题,而utf-8-sig需要提供BOM(“ByteOrder Mark”) 实践指导 出现报错可以尝试 encoding="utf-8-sig" 具体案例及参考: https://blog.csdn.net/u011854875/article/details/78466585 ....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,155,498
精华内容 1,662,199
关键字:

utf-8和utf-16