为什么Javascript中的`atob()`和`btoa()`这样命名?

426
在Javascript中,window.atob()方法解码一个base64字符串,window.btoa()方法将一个string编码成base64格式。为什么它们没有像base64Decode()base64Encode()这样的名称呢?atob()btoa()并不合理,因为它们毫无语义。我想知道原因。

1
@Ryan 我知道它是“a到b”和“b到a”,但我仍然发音为“a-tob”和“b-toa”。 - Sebastian Simon
2
通常情况下,不要使用糟糕的“name”,而是使用清晰的长名称,例如“getElementById”、“addEventListener”。 - cieunteung
我也曾相信atob和btoa的名称是颠倒的,A是原始字符串,B是编码后的字符串,这是一个不幸的巧合,Base64与编码后的B字符串共享了初始字母。更加混乱的是,我在过去十年中才开始使用Linux,Linux提供了base64程序,所以我从来不需要知道btoa也能做同样的事情。我很少质疑命名选择,但经过多年的思考,我必须了解其中的原因。 - Minkiele
你可以使用函数abes46neoced(a){return swab(swab(atob(a))));,但需要编写自己的swab函数。 - Stephen Duffy
2
这是因为 atob 中的 'b' 代表二进制,而不是 base64。ASCII 是base64编码的,而字符串是二进制的。 - Janac Meena
@janac ASCII不是base64,如果有什么的话,也许可以说base64是ASCII的子集。但这也不完全正确,它只是用我们都认识的字母数字符号来表示。ASCII最初设计为7位即base128,而较新的utf-8格式和现在的utf-16是最常见的。Base256和base65536也存在,但没有人这样称呼它们。Base64被“创建”并用于确保旧设备之间的兼容性,因为一些设备在网络通信中使用7位,而另一些则使用6位。Base64是6位,因此可以在两者上运行。 - Robert Cotterman
5个回答

237

我在Twitter上向JavaScript的创造者Brendan Eich询问了这些名字是否由他选定,他回答道:

这些都是Unix旧版中的名称,虽然man页面很难找到,但可以参考https://www.unix.com/man-page/minix/1/btoa/。这些名称从Unix延续到了Netscape的代码库中,1995年(十天五月之后)我匆匆将它们反映到了JS中。

万一Minix链接失效,这里有man页面的内容:

BTOA(1)                                           BTOA(1)

NAME
       btoa - binary to ascii conversion

SYNOPSIS
       btoa [-adhor] [infile] [outfile]

OPTIONS
       -a     Decode, rather than encode, the file

       -d     Extracts repair file from diagnosis file

       -h     Help menu is displayed giving the options

       -o     The obsolete algorithm is used for backward compatibility

       -r     Repair a damaged file

EXAMPLES
       btoa <a.out >a.btoa # Convert a.out to ASCII

       btoa -a <a.btoa >a.out
               # Reverse the above

DESCRIPTION
       Btoa  is  a  filter that converts a binary file to ascii for transmission over a telephone
       line.  If two file names are provided, the first in used for input and the second for out-
       put.   If  only one is provided, it is used as the input file.  The program is a function-
       ally similar alternative to uue/uud, but the encoding is completely different.  Since both
       of  these are widely used, both have been provided with MINIX.  The file is expanded about
       25 percent in the process.

SEE ALSO
       uue(1), uud(1).

50
好的,这是对楼主问题的实际回答。 - Ivan Filho
1
感谢您对这两种方法命名的权威和历史解释。 - Константин Ван
在我的脑海中,我总是将函数扩展为asciiToBase64和base64ToAscii,这总是让我感到困惑,因为它们实际上恰好相反。那个答案终于给出了一个合理的解释,甚至有些道理。希望我的大脑能够理解并接受这个解释 :) - undefined

218
atob()btoa()方法允许作者将内容转换为base64编码并从中恢复。

在这些API中,出于记忆的目的,“b”可以被认为代表“二进制(binary)”,“a”代表“ASCII”。但实际上,基于主要历史原因,这些函数的输入和输出都是Unicode字符串。

来源: http://www.w3.org/TR/html/webappapis.html#atob


127
但是这里有点反了。atob()将二进制转换为ASCII码,而btoa()则将ASCII码转换为二进制。 - 2540625
82
ASCII 是 Base64 编码,而atob是 ASCII 到二进制的转换。两个回答中都没提到这一点。因此这不是一个反向转换。 - AKnox
21
所以String是二进制的?我一直认为二进制只有0和1,这太令人困惑了! - Stefan Rein
12
@StefanRein 我同意你的观点。window.btoa 会将其参数作为二进制数据读取,并将其分成6位一组的块以进行编码;从某种角度来看,这个命名是有道理的。然而,window.btoa 只接受一个字符串作为其参数!:( - Константин Ван
9
“然而,window.btoa只接受一个字符串作为参数!” 这是正确的,但这里的字符串只是数据的表示。就像在记事本中打开图像时会显示为字符串,但它仍然是二进制数据。 btoa的主要优势在于它不关心字符串的格式,它将其视为二进制数据。仅仅巧合的是,在大多数情况下,该字符串恰好是一个常规字符串。 - laggingreflex
显示剩余9条评论

184

总结已经给出的答案:

  • atob代表ASCII转二进制
    • 例如:atob("ZXhhbXBsZSELCg==") == "example!^K"
  • btoa代表二进制转ASCII
    • 例如:btoa("\x01\x02\xfe\xff") == "AQL+/w=="

为什么使用ASCII和binary:

  • ASCIIa)是base64编码的结果。这是一个由ASCII字符(*)子集组成的安全文本,可以正确表示和传输(例如,电子邮件的正文),
  • binaryb)是任何一串01(在JavaScript中必须用字符串类型表示)。

(*) 在base64中限制为:A-Z, a-z, 0-9, +, /= (填充,仅在末尾) https://en.wikipedia.org/wiki/Base64

P.S. 我必须承认,最初我自己也对命名感到困惑,并认为名称被交换了。我以为b代表"base64编码的字符串"a代表"任何字符串" :D。


15
我认为你基本上证明了每个人的观点:base64是ASCII的一个子集,因此尽管您可能会争辩说btoa的输出仍然在技术上是ASCII,但没有理由将只接受base64作为输入的函数命名为atob - devios1
4
把'a'(ascii)看做base64输出,把'b'(binary)看做由0和1组成的字符串流,这样思考和记忆会更有帮助。 - Talespin_Kit

85

这些名字来自于一个类似功能的unix函数btoa,但您可以在其他答案中已经看到它了。


下面是一个助记口诀,帮助你记住该使用哪个函数。这并没有真正回答问题本身,但可能有助于人们弄清楚哪个函数适合使用,而不必整天都在stackoverflow上保持此问题的标签打开。

美丽转丑恶 btoa

将美丽的东西(例如:应用程序可以理解的美好内容,如json、xml、文本、二进制数据)转换成难以理解的丑陋之物(即进行编码)。

丑恶至美丽 atob

btoa完全相反。

注意

有些人可能会说二进制数据不够美丽,但是嘿,这只是一个助记技巧来帮助您。


1
这个记忆方法似乎比记住名字实际代表的意思“二进制转ASCII”更令人困惑。在你的记忆方法中,二进制内容可能甚至不包含可打印字符,却被认为是“美丽”的,而ASCII内容却被认为是“糟糕”的,这似乎有些不合常理。 - undefined

8

目前我还无法找到来源,但众所周知,在这种情况下,b代表“二进制”,a代表“ASCII”。

因此,实际上函数的名称是:

ASCII转二进制用于atob(),而 二进制转ASCII用于btoa()

请注意,这是浏览器实现,仅为了保留遗留代码和向后兼容。例如,在Node.js中,这些函数不存在。


4
在 Node 中,您可以使用 Buffer.from("Hello World").toString('base64')Buffer.from("SGVsbG8gV29ybGQ=", 'base64').toString('ascii') - Nanoo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接