精华内容
下载资源
问答
  • UTF-8的BOM是什么意思

    万次阅读 2019-06-11 08:22:05
    BOM:byte order mark,定义字节顺序,因为网络传输中分为两种,大头和小头。uft-8不需要bom表明字节顺序,...微软在utf-8中使用bom是因为这样可以把UTF-8和ASCII等编码区分开来,但这样的文件在windows之外的操作系...

    BOM:byte order mark,定义字节顺序,因为网络传输中分为两种,大头和小头。uft-8不需要bom表明字节顺序,但可以用BOM来表示编码方式,windows就是采用bom来标记文本文件的编码方式的。

    bom是为utf-16和utf-32准备的,用于标记字节顺序。微软在utf-8中使用bom是因为这样可以把UTF-8和ASCII等编码区分开来,但这样的文件在windows之外的操作系统里会带来问题。

    不含bom的UTF-8才是标准形式。UTF-8」和「带 BOM 的 UTF-8」的区别就是有没有 BOM。即文件开头有没有 U+FEFF。
    UTF-8 的网页代码不应使用 BOM,否则常常会出错。这是一个小例子: 为什么这个网页代码 <head> 内的信息会被浏览器理解为在 <body> 内?

    展开全文
  • UTF-8和不带BOM的UTF-8什么区别?

    千次阅读 2019-12-20 09:24:02
    没有BOM的 UTF-8UTF-8什么区别? 哪个更好?

    没有BOM的 UTF-8和UTF-8有什么区别? 哪个更好?


    #1楼

    我从另一个角度看待这个问题。 我认为带有BOM的UTF-8更好,因为它提供了有关文件的更多信息。 仅当遇到问题时,我才使用不带BOM的UTF-8。

    我长时间在页面上使用多种语言(甚至是西里尔字母 ),并且在保存文件时不使用BOM并重新打开它们以使用编辑器进行编辑(如cherouvim所述),某些字符已损坏。

    请注意,当您尝试使用UTF-8编码保存新创建的文件时,Windows的经典记事本会自动使用BOM表保存文件。

    我个人保存带有BOM的服务器端脚本文件(.asp,.ini,.aspx) 带有BOM的 .html文件


    #2楼

    具有BOM的UTF-8可以更好地识别。 我已经很难得出这个结论。 我正在一个项目中,结果之一是一个CSV文件(包括Unicode字符)。

    如果保存的CSV文件没有BOM表,则Excel会认为它是ANSI并显示乱码。 一旦在前面添加了“ EF BB BF”(例如,通过使用带UTF-8的记事本重新保存它;或带UTF-8的BOM一起使用Notepad ++),Excel就会很好地打开它。

    RFC 3629建议将BOM表字符添加到Unicode文本文件中:“ UTF-8,ISO 10646的转换格式”,2003年11月,位于http://tools.ietf.org/html/rfc3629 (此最新信息位于: http://www.herongyang.com/Unicode/Notepad-Byte-Order-Mark-BOM-FEFF-EFBBBF.html


    #3楼

    当您要显示以UTF-8编码的信息时,您可能不会遇到问题。 例如,将HTML文档声明为UTF-8,您将在浏览器中显示包含在文档正文中的所有内容。

    但是,当我们在Windows或Linux上拥有文本, CSV和XML文件时,情况并非如此。

    例如,Windows或Linux中的文本文件是可以想到的最简单的东西之一,它不是(通常)UTF-8。

    将其另存为XML并声明为UTF-8:

    <?xml version="1.0" encoding="UTF-8"?>
    

    即使已声明为UTF-8,它也不会正确显示(不会被读取)。

    我有一串包含法语字母的数据,需要将其另存为XML以供联合使用。 无需从一开始就创建UTF-8文件(更改IDE中的选项和“创建新文件”)或在文件的开头添加BOM表

    $file="\xEF\xBB\xBF".$string;
    

    我无法将法语字母保存在XML文件中。


    #4楼

    将BOM放入UTF-8编码的文件中至少存在三个问题。

    1. 不包含任何文本的文件不再为空,因为它们始终包含BOM。
    2. 包含UTF-8 ASCII子集内的文本的文件本身不再是ASCII,因为BOM不是ASCII,这会使某些现有工具失效,并且用户无法替换这些旧版工具。
    3. 无法将多个文件连接在一起,因为现在每个文件的开头都有一个BOM。

    而且,正如其他人提到的那样,拥有BOM表来检测某物是否为UTF-8既不充分,也没有必要:

    • 这是不够的,因为任意字节序列可能会以构成BOM的确切序列开头。
    • 这是没有必要的,因为您可以像读取字节一样将它们当作UTF-8读取。 如果成功,按照定义,它是有效的UTF-8。

    #5楼

    如果您在HTML文件中使用UTF-8,在同一页面中使用塞尔维亚西里尔字母,塞尔维亚拉丁语,德语,匈牙利语或其他外来语言,则带有BOM的UTF更好。 我的观点是(计算机和IT行业已有30年的历史)。


    #6楼

    如上所述,带有BOM的UTF-8可能会导致非BOM感知(或兼容)软件出现问题。 我曾经使用基于Mozilla的KompoZer编辑了编码为UTF-8 + BOM的HTML文件,因为客户端要求使用所见即所得程序。

    保存时,布局总是会被破坏。 我花了一些时间来解决这个问题。 这些文件在Firefox中运行良好,但是在Internet Explorer中显示CSS异常,再次破坏了布局。 摆弄了几个小时的CSS链接无济于事之后,我发现Internet Explorer不喜欢BOMfed HTML文件。 再也不。

    另外,我刚刚在Wikipedia中找到了这个:

    shebang字符由扩展ASCII编码中的相同两个字节表示,包括UTF-8,UTF-8通常用于当前类Unix系统上的脚本和其他文本文件。 但是,UTF-8文件可以以可选的字节顺序标记(BOM)开头; 如果“ exec”功能专门检测到字节0x23 0x21,则在shebang之前存在BOM(0xEF 0xBB 0xBF)将阻止脚本解释器被执行。 为此,一些权威人士建议不要在POSIX(类似Unix的)脚本中使用字节顺序标记,[15]并出于更广泛的互操作性和哲学考虑


    #7楼

    一个实际的区别是,如果您为Mac OS X编写了一个shell脚本并将其另存为普通UTF-8,则将得到响应:

    #!/bin/bash: No such file or directory
    

    响应shebang行,指定您要使用的外壳:

    #!/bin/bash
    

    如果另存为UTF-8,则没有BOM(例如BBEdit )都可以。


    #8楼

    没有BOM的UTF-8没有BOM,这不会比带有BOM的UTF-8更好,除非文件的使用者需要知道(或会从中获知)文件是否为UTF-8编码或不。

    BOM通常可用于确定编码的字节序,这在大多数情况下不是必需的。

    此外,对于那些不了解或不关心BOM的用户而言,BOM可能是不必要的噪音/痛苦,并可能导致用户困惑。


    #9楼

    http://en.wikipedia.org/wiki/Byte-order_mark

    字节顺序标记(BOM)是Unicode字符,用于表示文本文件或流的字节序(字节顺序)。 它的代码点是U + FEFF。 BOM的使用是可选的,并且如果使用的话,应出现在文本流的开始。 除了将其特定用作字节顺序指示符之外,BOM字符还可以指示文本在几种Unicode表示形式中的哪一种编码。

    始终在文件中使用BOM将确保始终在支持UTF-8和BOM的编辑器中正确打开它。

    我缺少BOM的真正问题如下。 假设我们有一个包含以下内容的文件:

    abc
    

    如果没有BOM,则在大多数编辑器中都将以ANSI的形式打开。 因此,此文件的另一个用户将其打开并附加一些本机字符,例如:

    abg-αβγ
    

    糟糕...现在该文件仍在ANSI中,请猜测“αβγ”不占用6个字节,而是3个。这不是UTF-8,这会在以后的开发链中引起其他问题。


    #10楼

    UTF-8 BOM是文本流(EF BB BF)开头的字节序列,它使读者可以更可靠地猜测文件是否已以UTF-8编码。

    通常,BOM用来表示编码的字节序,但是由于字节序与UTF-8不相关,因此不需要BOM。

    根据Unicode标准不建议使用UTF-8文件BOM

    2.6编码方案

    ...对于UTF-8既不需要也不建议使用BOM,但是在从使用BOM的其他编码形式转换UTF-8数据或BOM用作UTF-8签名的情况下可能会遇到BOM。 。 有关更多信息请参见第16.8节特价 ”中的“字节顺序标记”小节。


    #11楼

    在BOM表的Wikipedia页面的底部引用: http : //en.wikipedia.org/wiki/Byte-order_mark#cite_note-2

    “对于UTF-8,既不需要也不建议使用BOM,但是在从使用BOM的其他编码形式转换UTF-8数据或BOM用作UTF-8签名的情况下,可能会遇到BOM的情况。”


    #12楼

    其他出色的答案已经回答:

    • UTF-8和使用BOM的UTF-8之间没有官方区别
    • BOM格式的UTF-8字符串将从以下三个字节开始。 EF BB BF
    • 从文件/流中提取字符串时,必须忽略这些字节(如果存在)。

    但是,作为对此的附加信息,如果字符串以UTF-8编码,则UTF-8的BOM可能是“嗅觉”的好方法...或者它可以是任何其他编码形式的合法字符串...

    例如,数据[EF BB BF 41 42 43]可以是:

    • 合法的ISO-8859-1字符串“ABC”
    • 合法的UTF-8字符串“ ABC”

    因此,虽然通过查看第一个字节来识别文件内容的编码可能很酷,但您不应依赖它,如上面的示例所示

    编码应该是已知的,而不是不可分割的。


    #13楼

    仅当文件实际包含某些非ASCII字符时,带BOM的UTF-8才有用。 如果包含该文件,则不包含任何文件,那么它可能会破坏以前将文件解释为纯ASCII的旧应用程序。 这些应用程序遇到非ASCII字符时肯定会失败,因此我认为BOM仅应在文件可以且不应再解释为纯ASCII的情况下添加。

    编辑:仅想说明一下,我完全不希望使用BOM,如果一些旧的垃圾无法使用,则将其添加进去,并且替换该旧应用程序是不可行的。

    不要期望UTF8有BOM。


    #14楼

    问题:没有BOM的UTF-8和UTF-8有什么区别? 哪个更好?

    这是Wikipedia文章中有关字节顺序标记(BOM)的一些摘录,我相信这些摘录可为该问题提供可靠的答案。

    关于BOM和UTF-8的含义:

    Unicode标准允许使用UTF-8中BOM ,但不要求也不建议使用它。 字节顺序在UTF-8中没有任何意义,因此它在UTF-8中的唯一用途是一开始就表示文本流已以UTF-8编码。

    使用BOM的 参数

    不使用BOM的主要动机是与不支持Unicode的软件向后兼容。另一个不使用BOM的动机是鼓励将UTF-8用作“默认”编码。

    论据 使用BOM:

    使用BOM的理由是,如果没有BOM,则需要进行启发式分析以确定文件正在使用的字符编码。 从历史上看,这种区分各种8位编码的分析很复杂,容易出错,有时速度很慢。 有许多库可简化任务,例如Mozilla通用字符集检测器和Unicode国际组件。

    程序员错误地认为检测UTF-8同样困难(这不是因为绝大多数字节序列都是无效的UTF-8,而这些库试图区分的编码允许所有可能的字节序列)。 因此,并非所有支持Unicode的程序都执行这种分析,而是依赖BOM。

    特别是, Microsoft编译器和解释器以及Microsoft Windows上的许多软件(例如记事本)将无法正确读取UTF-8文本,除非它只有ASCII字符或以BOM表开头,并且在保存时将BOM表添加到开头文字为UTF-8。 将Microsoft Word文档下载为纯文本文件时,Google文档将添加BOM。

    使用 BOM表 使用BOM表 ,哪个更好

    IETF建议,如果协议(a)始终使用UTF-8,或者(b)使用某种其他方式指示所使用的编码,则该协议“应禁止使用U + FEFF作为签名”。

    我的结论:

    当与软件应用程序的兼容性是绝对必要的时才使用BOM。

    还要注意,虽然参考的Wikipedia文章指出许多Microsoft应用程序都依赖BOM来正确检测UTF-8,但并非所有 Microsoft应用程序都如此。 例如,如@barlop所指出的那样 ,当将Windows命令提示符与UTF-8 †一起使用时 ,此类和more type命令不会期望BOM表存在。 如果BOM 存在时,它可以是有问题的,因为它是用于其他应用。


    chcp命令通过代码页65001提供对UTF-8( BOM)的支持。


    #15楼

    请注意,对于某些文件,即使在Windows上也必须没有 BOM。 示例是SQL*plusVBScript文件。 如果此类文件包含BOM表,则在尝试执行它们时会出错。


    #16楼

    没有BOM的UTF-8和UTF-8有什么区别?

    简短的答案:在UTF-8中,BOM编码为文件开头的字节EF BB BF

    长答案:

    最初,预期Unicode将以UTF-16 / UCS-2编码。 BOM是为此编码形式设计的。 当您有2个字节的代码单元时,有必要指出这两个字节的顺序,并且通常的惯例是在数据的开头包含字符U + FEFF作为“字节顺序标记”。 字符U + FFFE是永久未分配的,因此它的存在可用于检测错误的字节顺序。

    无论平台的字节顺序如何,UTF-8的字节顺序都相同,因此不需要字节顺序标记。 但是,它可能会发生(作为字节序列EF BB FF )从UTF-16转换为UTF-8的数据中,或者作为“签名”表示该数据是UTF-8。

    哪个更好?

    没有。 正如Martin Cote回答的那样,Unicode标准不建议这样做。 它会导致非BOM感知软件出现问题。

    检测文件是否为UTF-8的更好方法是执行有效性检查。 UTF-8对有效的字节序列有严格的规定,因此误报的可能性可以忽略不计。 如果字节序列看起来像UTF-8,则可能是这样。


    #17楼

    这个问题已经有一百万个答案了,其中许多都很好,但是我想尝试弄清楚何时应该使用或不应该使用BOM。

    如上所述,在确定字符串是否为UTF-8时对UTF BOM(字节顺序标记)的任何使用都是有根据的猜测。 如果有适当的元数据(例如charset="utf-8" ),那么您已经知道应该使用什么,否则,您需要测试并做一些假设。 这涉及检查字符串来自的文件是否以十六进制字节码EF BB BF开头。

    如果找到了对应于UTF-8 BOM的字节码,则概率很高,可以假定它是UTF-8,您可以从那里开始。 但是,如果被迫做出这种猜测,那么在读取时进行额外的错误检查仍然是一个好主意,以防万一出现乱码。 如果输入绝对不是基于源的UTF-8,则应该仅假设BOM不是UTF-8(即latin-1或ANSI)。 但是,如果没有BOM,则可以通过对编码进行验证来简单地确定它是否应为UTF-8。

    为什么不建议使用BOM?

    1. 不支持Unicode或不兼容的软件可能会认为它是latin-1或ANSI,并且不会从字符串中删除BOM,这显然会引起问题。
    2. 并不是真正需要的(只需检查内容是否符合要求,当找不到符合要求的编码时,始终使用UTF-8作为后备)

    什么时候应该使用BOM编码?

    如果您无法以其他任何方式(通过字符集标记或文件系统元数据)记录元数据,并且无法像BOM一样使用程序,则应使用BOM进行编码。 在Windows上尤其如此,在Windows上,通常假定没有BOM的任何东西都在使用旧版代码页。 BOM告诉Office之类的程序,是的,该文件中的文本为Unicode。 这是使用的编码。

    说到它,我真正真正遇到过的唯一文件是CSV。 根据程序,它要么必须具有BOM,要么必须没有BOM。 例如,如果您在Windows上使用Excel 2007+,则要平滑打开它而不必求助于导入数据,则必须使用BOM对其进行编码。


    #18楼

    这是一个古老的问题,有很多好的答案,但应该增加一件事。

    所有答案都很笼统。 我要添加的是实际上会导致实际问题的BOM用法示例,但是很多人对此并不了解。

    BOM中断脚本

    Shell脚本,Perl脚本,Python脚本,Ruby脚本,Node.js脚本或需要由解释程序运行的任何其他可执行文件-所有这些都以shebang行开头,该看起来像其中之一:

    #!/bin/sh
    #!/usr/bin/python
    #!/usr/local/bin/perl
    #!/usr/bin/env node
    

    它告诉系统调用此类脚本时需要运行哪个解释器。 如果脚本以UTF-8编码,则可能会想在开始时包含BOM。 但是实际上是“#!” 字符不仅仅是字符。 实际上,它们是一个魔术数字 ,恰好由两个ASCII字符组成。 如果在这些字符之前放置一些东西(例如BOM),则文件看起来像是具有不同的幻数,这可能会导致问题。

    参见维基百科, 文章:Shebang,章节:幻数

    shebang字符由扩展ASCII编码中的相同两个字节表示,包括UTF-8,UTF-8通常用于当前类Unix系统上的脚本和其他文本文件。 但是,UTF-8文件可以以可选的字节顺序标记(BOM)开头; 如果“ exec”功能专门检测到字节0x23和0x21,则在shebang之前存在BOM(0xEF 0xBB 0xBF)将阻止脚本解释器被执行。 为此,一些权威人士建议不要在POSIX(类Unix)脚本中使用字节顺序标记,[14]并出于更广泛的互操作性和哲学考虑。 另外,在UTF-8中不需要字节顺序标记,因为该编码不存在字节顺序问题。 它仅用于将编码标识为UTF-8。 [加重]

    BOM在JSON中是非法的

    参见RFC 7159第8.1节

    实现不得在JSON文本的开头添加字节顺序标记。

    BOM在JSON中是多余的

    不仅在JSON中是非法的,而且也不需要确定字符编码,因为存在更可靠的方法来明确确定任何JSON流中使用的字符编码和字节序(有关详细信息,请参见此答案 )。

    BOM破坏了JSON解析器

    它不仅在JSON中是非法的并且不需要 ,而且实际上破坏了使用RFC 4627中介绍的方法确定编码的所有软件

    确定JSON的编码和字节序,检查NUL字节的前4个字节:

    00 00 00 xx - UTF-32BE
    00 xx 00 xx - UTF-16BE
    xx 00 00 00 - UTF-32LE
    xx 00 xx 00 - UTF-16LE
    xx xx xx xx - UTF-8
    

    现在,如果文件以BOM表开头,它将如下所示:

    00 00 FE FF - UTF-32BE
    FE FF 00 xx - UTF-16BE
    FF FE 00 00 - UTF-32LE
    FF FE xx 00 - UTF-16LE
    EF BB BF xx - UTF-8
    

    注意:

    1. UTF-32BE不是以三个NUL开头,因此不会被识别
    2. UTF-32LE第一个字节后没有3个NUL,因此不会被识别
    3. UTF-16BE的前4个字节只有1个NUL,因此不会被识别
    4. UTF-16LE的前4个字节只有1个NUL,因此不会被识别

    根据实现的不同,所有这些都可能被错误地解释为UTF-8,然后被错误地解释或拒绝为无效的UTF-8,或者根本无法被识别。

    此外,如果实现按照我建议的那样测试有效的JSON,则即使该输入确实被编码为UTF-8,也将拒绝该输入,因为它不以RFC规定的ASCII字符<128开头。

    其他数据格式

    不需要JSON中的BOM,这是非法的,并且会破坏根据RFC正常运行的软件。 那时不使用它应该是一个明智的选择,但是总有些人坚持通过使用BOM,注释,不同的引用规则或不同的数据类型来破坏JSON。 当然,任何人都可以自由使用BOM或其他任何需要的东西-那就不要将其称为JSON。

    对于除JSON之外的其他数据格式,请看一下它的实际外观。 如果唯一的编码是UTF- *,并且第一个字符必须是小于128的ASCII字符,那么您已经拥有确定数据的编码和字节序所需的所有信息。 即使将BOM表作为可选功能添加,也只会使其更加复杂且容易出错。

    BOM的其他用途

    至于JSON或脚本之外的用途,我认为这里已经有了很好的答案。 我想添加更多有关脚本和序列化的详细信息,因为这是导致实际问题的BOM字符的示例。


    #19楼

    Unicode 字节顺序标记(BOM)常见问题解答提供了一个简洁的答案:

    问:我应该如何处理BOM?

    答:以下是一些指导原则:

    1. 特定协议(例如,Microsoft .txt文件约定)可能要求在某些Unicode数据流(例如文件)上使用BOM。 当您需要遵循此类协议时,请使用BOM。

    2. 对于未加标签的文本,某些协议允许使用可选的BOM。 在那种情况下

      • 如果已知文本数据流是纯文本,但编码方式未知,则BOM可用作签名。 如果没有BOM,则编码可以是任何形式。

      • 如果已知文本数据流是纯Unicode文本(而不是哪个字节序),则BOM可用作签名。 如果没有BOM,则文本应解释为big-endian。

    3. 某些面向字节的协议期望在文件开头使用ASCII字符。 如果这些协议使用UTF-8,则应避免使用BOM作为编码形式签名。

    4. 在已知数据流的确切类型的地方(例如Unicode大端或Unicode小端),不应使用BOM。 特别是,每当数据流声明为UTF-16BE,UTF-16LE,UTF-32BE或UTF-32LE时,都不得使用BOM。


    #20楼

    这是我对Visual Studio,SourceTree和Bitbucket拉取请求的经验,这给了我一些问题:

    因此,在审查请求请求时,带有签名的BOM会在每个文件上包含一个红点字符(可能会很烦人)。

    在此处输入图片说明

    如果将鼠标悬停在它上面,它将显示一个类似于“ ufeff”的字符,但结果表明sourcetree没有显示这些类型的字节标记,因此它很可能最终出现在您的请求中,这应该没问题,因为VS 2017就是这样编码的现在是新文件,所以也许bitbucket应该忽略此文件或以其他方式显示它,更多信息请参见:

    红点标记BitBucket差异视图


    #21楼

    BOM倾向于在某个地方某个地方繁荣(没有双关语意)。 而且当它蓬勃发展时(例如,未被浏览器,编辑器等识别),它显示为文档开头的奇怪字符 (例如HTML文件, JSON响应, RSS ,等),并导致这种尴尬,例如奥巴马在Twitter上的谈话中遇到最近编码问题

    当它出现在难以调试的地方或忽略测试时,这很烦人。 因此,除非您必须使用它,否则最好避免它。

    展开全文
  • 下面我们就来了解一下 Unicode 和 UTF-8 编码到底有什么关系。 要弄清 Unicode 与 UTF-8 的关系,我们还得从他们的来源说起,下来我们从刚开始的编码说起,直到 Unicode 的出现,我们就会感觉到他们之间的关系  ...

    想必做过爬虫的同学肯定被编码问题困扰过,有 UTF-8、GBK、Unicode 等等编码方式,但你真的了解其中的原理吗?下面我们就来了解一下 Unicode 和 UTF-8 编码到底有什么关系。

    要弄清 Unicode 与 UTF-8 的关系,我们还得从他们的来源说起,下来我们从刚开始的编码说起,直到 Unicode 的出现,我们就会感觉到他们之间的关系 

    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 

    先来看简单的 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 的一种实现。

    展开全文
  • 除了 让编辑器知道它是个utf-8之外什么用处都没有。 实际上编辑器完全有能力在不太多的几个编码格式之间根据特征来判断一个文件是什么编码,就算不能自动识 别,编辑器也应该有设置编码的地方。所以我觉得BOM对于utf...

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/forest_fire/article/details/50943980

    BOM——Byte Order Mark,就是字节序标记

     

    在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输 字符"ZERO WIDTH NO-BREAK SPACE"。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little- Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被称作BOM。

     

    UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。

     

    UTF- 8编码的文件中,BOM占三个字节。如果用记事本把一个文本文件另存为UTF-8编码方式的话,用UE打开这个文件,切换到十六进制编辑状态就可以看到开 头的FFFE了。这是个标识UTF-8编码文件的好办法,软件通过BOM来识别这个文件是否是UTF-8编码,很多软件还要求读入的文件必须带BOM。可 是,还是有很多软件不能识别BOM。

     

    在Firefox早期的版本里,扩展是不能有BOM的,不过Firefox 1.5以后的版本已经开始支持BOM了。现在又发现,PHP也不支持BOM。PHP在设计时就没有考虑BOM的问题,也就是说他不会忽略UTF-8编码的文件开头BOM的那三个字符

     

    由 于必须在在Bo-Blog的wiki看到,同样使用PHP的Bo-Blog也一样受到BOM的困扰。其中有提到另一个麻烦:“受COOKIE送出机制的限 制,在这些文件开头已经有BOM的文件中,COOKIE无法送出(因为在COOKIE送出前PHP已经送出了文件头),所以登入和登出功能失效。一切依赖 COOKIE、SESSION实现的功能全部无效。”这个应该就是Wordpress后台出现空白页面的原因了,因为任何一个被执行的文件包含了BOM, 这三个字符都将被送出,导致依赖cookies和session的功能失效。

     

    解决的办法嘛,如果只包含英 文字符(或者说ASCII编码内的字符),就把文件存成ASCII码方式吧。用UE等编辑器的话,点文件->转换->UTF-8转 ASCII,或者在另存为里选择ASCII编码。如果是DOS格式的行尾符,可以用记事本打开,点另存为,选ASCII编码。如果包含中文字符的话,可以 用UE的另存为功能,选择“UTF-8 无 BOM”即可。

     

    utf-8本来就不应该加bom,除了 让编辑器知道它是个utf-8之外什么用处都没有。实际上编辑器完全有能力在不太多的几个编码格式之间根据特征来判断一个文件是什么编码,就算不能自动识 别,编辑器也应该有设置编码的地方。所以我觉得BOM对于utf-8来说是多余的东西。

     

    utf-16才需要加bom。因为它是按unicode顺序编码,在BMP范围内是二字节,需要识别是大或小字节序。

     

    实 际上,我觉得utf-8引入大小字节序的概念太愚蠢了,不知道那些标准委员会是怎么想的。大小字节序存在的意义,在于cpu的处理方式。如果cpu是大字 节序处理,那么对于小字节序,就必须做一层转换,这带来了效率上的下降。但是在实际应用里,谁会去关心大小字节序?文本编码引起字节序的概念,只能说那些 制定标准的人太死板了。对于utf-16,我认为只要全世界都遵循一种字节序方式,那就没什么必要用BOM来标注了。

     

    话说回来,PHP是不支持utf-16编码的文件的。因为例如$这个符号,在utf-8里也是两个字节,PHP解码器无法解析的。不知道PHP6内部处理引入unicode 的概念之后,对这个是否会有支持。

     

    编 码问题是一个说起来简单,但是实际上很繁琐的东西。很多程序,都有分层编码的概念。像MySQL,就分为 client->connection->storage和storage->connection->result这些概念。 storage又分为system,database,table,column。我有时候在想,有必要搞这么复杂嘛,TNND。像MySQL,谁用利用 它这些特性阿?除非允许两个client在不同的编码环境下运作,否则它把client编码分离出来根本没有什么必要。大多数情况下,直接binary in/binary out就好了

    【为什么这个网页代码 <head> 内的信息会被浏览器理解为在 <body> 内?】

    <head> 嵌套错误是因为整个 HTML 文档的最开头多了一个看不见的 U+FEFF(就在「<!DOCTYPE」前面),它污染了 HTML。

    U+FEFF 就是我们常说的「BOM(byte order mark)」,也是 @董鹏 说的「signature」,UTF-8 编码的文件不需要它。Windows 该死的记事本有个臭名昭著的破毛病就是在 UTF-8 文件开头加 BOM,所以不要用记事本来编辑文件。
    可以用在线工具检查你的网页是否被多余的 BOM 污染了

    作者:梁海
    链接:https://www.zhihu.com/question/20138814/answer/14100483
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • utf-8与带有BOM的utf-8的区别

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

    万次阅读 多人点赞 2017-11-30 17:11:56
    1) UTF-8 UTF-8 的编码规则很简单:如果只有一个字节,那么最高的比特位为 0;如果有多个字节,那么第一个字节从最高位开始,连续有几个比特位的值为 1,就使用几个字节编码,剩下的字节均以 10 开头。 具体的表现...
  • UTF-8】文件转换为utf-8编码

    千次阅读 2019-06-21 17:32:59
    它的存在干扰了软件使用UTF-8,所以不带最好 问题 在日常的编程过程中,有时需要合作开发,不同的人用不同的软件打开的文件有时编码格式不一样,特别是采用了中文的GB2312等等,用软件打开可能就是乱码!!! 其实一两...
  • Python encode方法:XX.encode(‘utf-8’)究竟是什么? 在Python学习中,我们经常会碰到这些内容: S.encode([encoding='utf-8'][,errors='strict']) 这时,我们会想等会去看看这究竟是什么?然后,就没有等会了。...
  • Eclipse修改编码为UTF-8

    千次阅读 2019-01-09 19:50:12
    Eclipse修改编码为UTF-8 第一步:修改工作空间编码 Window --&gt; Preferences --&gt; Workspaces --&gt; Text file encoding --&gt; Other --&gt; UTF-8 --&gt; Apply 第二步:修改项目...
  • utf-8utf-8-sig的区别(CSV文件 乱码)

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

    万次阅读 2017-05-12 17:24:22
    博客核心内容:1、python文件开头utf-8格式的理解 2、程序中读取文件时utf-8格式的理解代码示例:#!/usr/bin/python # -*- coding:utf-8 -*-fr1 = open("goods_information", "r", encoding="utf-8") print(fr1....
  • utf-8utf-8-sig 两种编码格式区别

    千次阅读 2019-02-06 13:40:48
    转:...   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)...
  • 【Encoding】UTF-8编码规则

    万次阅读 2017-10-23 15:32:50
    UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。...
  • java 乱码问题-Dfile.encoding=UTF-8

    千次阅读 2018-06-26 10:40:54
    windows环境编码GBK、Linux环境下没有出现异常时默认编码是utf8、异常时虽然 系统环境显示utf-8,但是因为安装了一些涉及系统环境的包之后,对编码为utf-8有些 许怀疑程序中转换的最终编码utf-8怀疑对象是程序运行...
  • charset=”utf-8”是告知浏览器此页面属于什么字符编码格式,下一步浏览器做好“翻译”工作。常见的字符编码有:gb2312、gbk、unicode、utf-8。各个字符编码含义: gb2312:代表国家标准第2312条,其中是不包含繁体...
  • python文件开头声明UTF-8编码的几种常用形式

    万次阅读 多人点赞 2019-05-14 15:39:54
    Python默认ASCII编码,如包含中文,为防止乱码,往往需要在编码开头重新声明编码类型 常用的形式有以下几种,... -*- : # -*- coding: utf-8 -*- 2. # coding=<encoding name> : # coding=utf-8 3. # codi...
  • utf-8utf-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以字节为...
  • TXT中文 保存为utf-8格式

    千次阅读 2019-02-11 20:46:17
  • 我们平时看到的文本文件,虽然都是文本,但有的是GBK编码,有的UTF-8编码。那么,对于一个阅读器,它在读取一个文本文件时如何知道它是GBK还是UTF-8呢? 奥秘在于文件头部的几个字节。 规定如下:当以UTF16或UTF...
  • python中编码问题很复杂,我曾尝试写了一篇有关于此的文章,但是总觉得有些问题的细节没有完全说清楚。所以决定重新把复杂问题分解为...# -*- coding: utf-8 -*- 其中的utf-8可以换成其他编码。 这篇文章就来说说这...
  • 是不是代表着本次连接的所有 查询语句 按utf-8去编码 再传给mysql数据库服务器
  • @[憨憨学代码](关于使用Notepad++的 UTF-8UTF-8-BOM) 谨在此记录一些我自己学习过程中的问题和想法。以下所述若有不妥之处,欢迎大家批评指正,也希望大家多提出宝贵意见和建议。 将Notepad++编码格式设置为UTF-8无...
  • UTF-8

    万次阅读 多人点赞 2019-07-10 13:53:46
    UTF-8编码规则 UTF-8是Unicode的一种实现方式,也就是它的字节结构有特殊要求,所以我们说一个汉字的范围是0X4E00到0x9FA5,是指unicode值,至于放在utf-8的编码里去就是由三个字节来组织,所以可以看出unicode是给...
  • Python中关于coding=utf-8以及中文字符前加u的解释

    万次阅读 多人点赞 2018-02-05 20:19:13
    写了很久的Python了,每次写之前都要在开头加上coding=utf-8,只知道是设置编码格式,但并没有太在意,今天在写socket编程时才发现编码格式的重要性。 一、关于开头coding=utf-8 开头的coding=utf-8和coding:utf-8的...
  • 就需要把文件编码类型改为UTF-8的类型,输入这个代码就可以让PY源文件里面有中文了。 建议你写代码之前都把这句话加上,因为不管是注释还是弹出消息提示, 免不了的要输入中文,所以这个基本是必须的。 ht....
  • #coding=utf-8的作用 还是乱码

    万次阅读 2017-08-21 23:37:18
    乱码产生的原因是Python在读取时默认解码方式是用操作系统编码,如果和保存时的...因为windows默认的编码方式是GBK,python文件保存时使用了utf-8,在读取时,python使用GBK的编码表去解utf-8编码的字节码,因为GBK与UT
  • MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。好在utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用utf...
  • UTF-16转UTF-8的方法,防止文件有BOM头

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

    千次阅读 2020-07-04 22:07:06
    把编辑器和浏览器的字符集统一设置成utf-8或者gbk即可。 主要区别: 1.GBK是在bai国家标准GB2312基础上扩容后兼容GB2312的标准(好像还不du是国家标准)。zhiGBK编码dao专门用来解决中文编码的,是双字节的。...
  • 于是就会有人产生疑问,UTF-8 既然能保存那么多文字、符号,为什么国内还有这么多使用 GBK 等编码的人?因为 UTF-8 等编码体积比较大,占电脑空间比较多,如果面向的使用人群绝大部分都是中国人,用 GBK 等编码也...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 193,474
精华内容 77,389
关键字:

utf-8是什么意思