代码之家  ›  专栏  ›  技术社区  ›  Aakash Goel

为什么要用Base64?

  •  208
  • Aakash Goel  · 技术社区  · 15 年前

    Wikipedia

    010011010110000101101110 作为 Man ASCII或as格式 TWFu 在Base64中,最终将存储相同的位模式。

    如果最终的编码是用0和1表示的,并且每台机器和媒体都能处理它们,那么数据是用ASCII还是Base64表示又有什么关系呢?


    谢谢大家,我想我现在明白了。

    当我们发送数据时,我们不能确定数据是否会以我们预期的格式进行解释。因此,我们发送以双方都能理解的某种格式(如Base64)编码的数据。这样,即使发送方和接收方对相同的内容有不同的解释,但由于他们同意编码格式,数据也不会被错误地解释。

    Mark Byers example

    如果我想送

    Hello
    world!
    

    一种方法是像ASCII一样发送

    72 101 108 108 111 10 119 111 114 108 100 33
    

    83 71 86 115 98 71 56 115 67 110 100 118 99 109 120 107 73 61 61
    

    它以相同信息量传输更多数据为代价,确保接收机能够以预期的方式解码数据,即使接收机碰巧对字符集的其余部分有不同的解释。

    12 回复  |  直到 7 年前
        1
  •  360
  •   Real Ambush    4 年前

    第一个错误是认为ASCII编码和Base64编码可以互换。他们不是。它们用于不同的目的。

    • 在Base64中编码数据时,从字节序列开始,并将其转换为文本字符串。

    为了理解为什么Base64首先是必要的,我们需要一点计算的历史。


    计算机以二进制(0和1)进行通信,但人们通常希望用更丰富的形式(如文本或图像)进行通信。为了在计算机之间传输这些数据,首先必须将其编码为0和1,发送,然后再次解码。以文本为例,有许多不同的方法来执行这种编码。如果我们都能就一种编码达成一致意见,那就简单多了,但遗憾的是,事实并非如此。

    Baudot code ASCII

    Base64 引入了编码技术。这允许您将任意字节编码为已知可以安全发送而不会损坏的字节(ASCII字母数字字符和一些符号)。缺点是使用Base64编码消息会增加其长度—每3个字节的数据被编码为4个ASCII字符。

    第一 Base64将生成的二进制数据编码为文本字符串,该字符串可以安全地以ASCII编码发送。接收方必须反转此过程才能恢复原始消息。当然,这需要接收器知道使用了哪些编码,并且这些信息通常需要单独发送。

    历史上,它一直被用来编码电子邮件中的二进制数据,其中电子邮件服务器可能会修改行尾。一个更现代的例子是使用Base64编码 embed image data directly in HTML source code


    下面是一个工作示例:

    我想发一条有两行文字的短信:

    Hello
    world!
    

    72 101 108 108 111 10 119 111 114 108 100 33
    

    字节10在某些系统中已损坏,因此我们可以将这些字节编码为Base64字符串:

    SGVsbG8Kd29ybGQh

    当使用ASCII编码时,如下所示:

    83 71 86 115 98 71 56 75 100 50 57 121 98 71 81 104
    

    这里的所有字节都是已知的安全字节,因此任何系统损坏此消息的可能性都很小。我可以发送此消息而不是原始消息,并让接收者反转过程以恢复原始消息。

        2
  •  67
  •   Sridhar Sarnobat    7 年前

    假设您想在XML文档中嵌入两个图像。图像是二进制数据,而XML文档是文本。但是XML不能处理嵌入的二进制数据。你是怎么做到的?

    一种选择是用base64编码图像,将二进制数据转换成XML可以处理的文本。

    而不是:

    <images>
      <image name="Sally">{binary gibberish that breaks XML parsers}</image>
      <image name="Bobby">{binary gibberish that breaks XML parsers}</image>
    </images>
    

    <images>
      <image name="Sally" encoding="base64">j23894uaiAJSD3234kljasjkSD...</image>
      <image name="Bobby" encoding="base64">Ja3k23JKasil3452AsdfjlksKsasKD...</image>
    </images>
    

    XML解析器能够正确地解析XML文档并提取图像数据。

        3
  •  41
  •   Billy ONeal IS4    15 年前

    为什么不看看呢 the RFC that currently defines Base64 ?


    环境中的数据 遗留原因,仅限于 US-ASCII码[1]数据库编码can 没有遗留限制, 只是因为它使这成为可能 使用文本操纵对象的步骤 编辑。

    在过去,不同的应用 有不同的要求和 编码略有不同 有时使用基本编码 没有准确的描述或者 扩展(MIME)[4]经常被使用 作为base64的参考 考虑到 角色。目的 规范是建立共同的 字母表和编码 注意事项。这很有希望 减少其他语言中的歧义

    Base64最初被设计为一种允许二进制数据作为多用途Internet邮件扩展的一部分附加到电子邮件的方法。

        4
  •  28
  •   Håvard S    15 年前

    为文本数据设计的媒体当然最终也是二进制的,但是文本媒体通常使用某些二进制值作为控制字符。此外,文本媒体可能会拒绝某些二进制值作为非文本。

    Base64编码将二进制数据编码为只能在文本媒体中解释为文本的值,并且不包含任何特殊字符和/或控制字符,因此数据也将在文本媒体中保留。

        5
  •  21
  •   Aiden Bell    15 年前

    更重要的是媒体 字符串编码,因此我们希望确保数据被处理应用程序接受(例如,不包含表示EOL的二进制序列)

    假设您想在一封编码为UTF-8的电子邮件中发送二进制数据——如果1和0的流创建了一个 序列 在UTF-8编码中不是有效的Unicode。

    当我们要对URL本身中对URL无效的字符进行编码时,URL中也会发生同样的情况:

    http://www.foo.com/hello 我的朋友-> http://www.foo.com/hello%20my%20friend

    这是因为我们想通过一个系统发送一个空间,这个系统会认为这个空间很臭。

    我们所做的只是确保在已知良好、可接受且无害的位序列到另一个位的文字序列之间存在1对1的映射,并且处理应用程序 无法区分

    在你的例子中, man 在第一种形式中可能是有效的ASCII;但通常您可能希望传输随机二进制值(即在电子邮件中发送图像):

    MIME版本:1.0
    内容描述:“a.gif的Base64编码”
    内容类型:image/gif;name=“a.gif”

    内容配置:附件;filename=“a.gif”

        6
  •  15
  •   Sridhar Sarnobat    6 年前

    Base64而不是转义特殊字符

    但是我想让我的ID无损地引用文件系统中的文件。现实中的文件可以有各种各样的奇怪和奇妙的字符,从感叹号,重音字符,波浪形,甚至表情符号!我不能这样做:

    <div id="/path/to/my_strangely_named_file!@().jpg">
        <img src="http://myserver.com/path/to/my_strangely_named_file!@().jpg">
        Here's a pic I took in Moscow.
    </div>
    

    # ERROR
    document.getElementById("/path/to/my_strangely_named_file!@().jpg");
    

    我认为这个代码执行时会失败。

    document.getElementById("18GerPD8fY4iTbNpC9hHNXNHyrDMampPLA");
    

    与使用MD5或其他一些散列函数不同,您可以反转编码以找出实际有用的数据。

    我希望我64年前就知道Base64了。我本来可以避免把头发扯下来的 encodeURIComponent str.replace(‘\n’,’\\n’)

    SSH文本传输:

        7
  •  13
  •   Community CDub    8 年前

    我觉得方便的一个例子是 embed binary data in XML . 一些二进制数据被SAX解析器误解了,因为这些数据可以是任何东西,包括XML特殊字符。Base64在发送端对数据进行编码,在接收端对其进行解码,解决了这个问题。

        8
  •  11
  •   casablanca    15 年前

    大多数计算机以8位二进制格式存储数据,但这不是要求。有些机器和传输介质一次只能处理7位(甚至更少)。这样的媒体将以7位的倍数来解释流,因此如果您要发送8位数据,您将无法在另一端接收到您期望的数据。Base-64只是解决此问题的一种方法:将输入编码为6位格式,通过介质发送,然后在接收端将其解码回8位格式。

        9
  •  7
  •   dan04    15 年前

    什么叫“媒体 用来处理文本数据?

    文本)而不是二进制数据(如.png和.jpg图像)。

    他们可以处理二进制=>他们可以 处理任何事情。

    • 字节0x0A和0x0D,用于行结束,因平台不同而不同。
    • 其他控制字符,如0x00(NULL=C字符串终止符)、0x03(文本结束)、0x04(传输结束)或0x1A(DOS文件结束),这些字符可能会提前发出数据结束的信号。
    • 无效的UTF-8字节序列。

    所以你不能仅仅通过基于文本的协议发送二进制数据。您仅限于表示非空格非控制ASCII字符的字节,其中有94个。选择base64的原因是使用2的幂更快,而64是最大的一个。

    但有一个问题。怎么回事 像这样常见的编码技术 UTF-8?

    A majority of sites use UTF-8 .

    事实上,微软似乎还没有克服选择了错误的UTF编码。如果要使用windowsapi或microsoftc运行时库,则只能使用UTF-16或区域设置的“ANSI”编码。这使得使用UTF-8非常痛苦,因为您必须一直转换。

        10
  •  6
  •   jamesdlin    15 年前

    除了其他(有些冗长)的答案:即使忽略仅支持7位ASCII的旧系统,以文本模式提供二进制数据的基本问题是:

    • 换行符通常以文本模式转换。
    • 必须注意不要将NUL字节视为文本字符串的结尾,这在任何具有C血统的程序中都非常容易做到。
        11
  •  5
  •   Mushtaq Hussain    7 年前

    为什么/如何使用Base64编码?

    Base64是一种二进制到文本的编码方案,效率为75%。它的使用使得典型的二进制数据(如图像)可以通过传统的“非8位干净”通道安全地发送。 在早期的电子邮件网络中(直到20世纪90年代初),大多数电子邮件都是7位US-ASCII字符集的纯文本。因此,许多早期的通信协议标准设计用于“7位”通信链路,“而不是8位干净的”。 方案效率是输入中的位数与编码输出中的位数之比。 十六进制(Base16)也是一种二进制到文本的编码方案,效率为50%。

    Base64编码步骤(简化):

    1. 每个6位组被转换成相应的Base64字符值,即Base64编码将三个八位字节转换成四个编码字符。输出字节与输入字节的比率为4:3(33%的开销)。
    2. 有趣的是,相同的字符将被不同的编码,这取决于它们在编码产生四个字符的三个八位组中的位置。
    3. 接收方必须反转此过程才能恢复原始消息。
        12
  •  3
  •   dirkgently    15 年前

    回到ASCII统治世界的那一天,处理非ASCII值是一件令人头痛的事。人们跳过各种各样的圈套,以便在不丢失信息的情况下通过电线传输这些信息。

        13
  •  2
  •   Gilbert    4 年前

    以下是我在阅读了别人的帖子后的理解总结:

    重要!

    Base64编码并不意味着提供安全性

    Base64编码并不意味着压缩数据

    为什么要用Base64

    Base64是数据的文本表示形式,仅由64个字符组成,这些字符是字母数字字符(小写和大写)、+、/和=。

    推荐文章