使用方法
- 把要编码的原文粘进上面的输入框,一行一段独立原文。页面打开时框里已经放好四行示例(
A、AB、ABC、柳泉工具A),结果区显示的就是它们各自编码后的结果,不用先点按钮。 - 选项按需勾选。默认勾着「按 UTF-8 转字节再编码」,这是中文能出结果的前提;「输出 URL-safe 字母表」把第 62、63 号符号从
+、/换成-、_;「按 MIME 每 76 字符折行」会在每满 76 个字符后插入CRLF,宽度可以在输入框里改成 4~998 之间的整数。 - 示例第 4 行
柳泉工具A是 4 个汉字加 1 个 ASCII 字母,UTF-8 下 4×3+1 = 13 字节,编出来是5p+z5rOJ5bel5YW3QQ==,末尾补 2 个=——因为 13 除以 3 余 1。 - 想看清
btoa()的真实脾气,把「按 UTF-8 转字节再编码」取消勾选再运行一次。工具会当场停下并指出是第几行第几个字符、码点是多少,而不是丢给你一串乱码。 - 输入框里按 Ctrl + Enter(macOS 用 Cmd + Enter)立刻编码。全部处理完点「复制结果」把整段带走,或者从下面的对照表导出 CSV。
这个 Base64编码工具能解决什么问题
一是把中文塞进只认 ASCII 的通道。邮件头、HTTP 基本认证、data URI、以及不少只允许 7 位字符的遗留协议,都不接受非 ASCII 字节。Base64编码把任意字节映射到 A–Z a–z 0–9 + / 这 64 个符号上,代价是体积涨三分之一,好处是这串字符在传输链路的每一段都不会被改写。
二是把二进制内容写成一行文本。证书、密钥、压缩包的片段要贴进配置文件、写进 JSON 字段、放进 issue 正文时,直接贴二进制一定会被编辑器或终端破坏,编码成 Base64 之后就可以当普通字符串处理。
三是弄明白「为什么我编出来的中文是乱码」。绝大多数在线工具只调用 btoa(str),而它按 HTML 标准只接受码点 0~255 的字符。中文汉字码点远大于 255,现代浏览器会直接抛 InvalidCharacterError,老工具则用 unescape(encodeURIComponent(s)) 硬绕。本页把这一步显式拆成「TextEncoder 转 UTF-8 字节 → 逐字节转字符 → btoa」,两边结果都能对着看。
四是避开 URL 传参的经典坑。标准字母表里的 + 在查询串中会被服务端按 application/x-www-form-urlencoded 规则解析成空格,/ 又会撞上路径分隔符。勾上「输出 URL-safe 字母表」把这两个符号换成 - 与 _,这串结果就能直接放进路径或参数里。
本页不做这些事:不把已经编码的串还原成原文、不给令牌拆分头部与载荷、不把文件整体读成 Base64。要反向操作请用页面底部的「Base32编码」查看同族的另一种字母表,或者去「Base64解码」把结果还原回文字。
编码原理:RFC 4648 §4 字母表、3 字节拆 4 个 6 位与填充规则
这个 Base64编码工具的核心只有三步:new TextEncoder().encode(str) 把原文变成 UTF-8 字节数组,再把字节按 3 个一组拼成 24 位、切成 4 个 6 位索引去查字母表,最后按剩余字节数补 =。三步里任何一步省略,结果都会和标准实现不一样。
字母表是 RFC 4648 第 4 节定义的 64 个符号,顺序固定不可换。下标 0~25 是大写 A–Z,26~51 是小写 a–z,52~61 是数字 0–9,62 是 +,63 是 /。以 ABC 为例:A 是 0x41、B 是 0x42、C 是 0x43,拼成 24 位是 01000001 01000010 01000011;按 6 位重切得到 010000、010100、001001、000011,也就是十进制 16、20、9、3,查表正好是 Q、U、J、D,连起来就是 QUJD。这就是「每 3 个字节换 4 个字符」的全部内容。
填充的个数由末尾剩下的字节数唯一决定。余 0 字节(正好整除)时不补,例如 ABC → QUJD;余 1 字节时补 2 个 =,例如 A → QQ==;余 2 字节时补 1 个 =,例如 AB → QUI=。补齐的位一律填 0,解码端靠填充数量反推「最后一组只该取几个字节」,所以 = 不是装饰,去掉它解码就会多出垃圾字节——这也是同一段文本在不同系统里长度不一致的常见原因。另外整除时不会也不该出现 ==== 这种四连填充。
中文必须走 UTF-8 字节,绕不开 btoa() 的限制。按 HTML 标准,btoa() 接受的字符串要求每个码点都落在 0~255,也就是 Latin-1 范围;柳 的码点是 U+67F3,换算成十进制是 26611,远超 255,直接传进去在 Chrome、Firefox、Safari 上都会抛 InvalidCharacterError: The string to be encoded contains characters outside of the Latin1 range. 正确顺序是先用 TextEncoder 把它编成 E6 9F B3 三个字节,再把这三个字节逐个 String.fromCharCode 拼成一个「每个字符码点都不超过 255」的临时串交给 btoa()。跳过这一步而直接用 Latin-1 处理 U+67F3,只会得到 0xF3 一个字节,结果自然对不上。
输出长度是 4 × ceil(n / 3),与输入内容无关。1024 字节固定得到 1368 个字符,100 字节得到 136 个字符,1 MiB(1048576 字节)分成 349526 组、输出 1398104 个字符,膨胀比恒为 4/3,也就是 +33.33%。注意这是逐段编码的下界:本页按行独立编码,每行各自补齐,所以四行示例 19 字节输出 32 个字符,而把这 19 字节当作一整块编码只需要 28 个字符——短行越多,填充带来的额外开销越大。
URL-safe 是另一个字母表,不是同一套的变体。RFC 4648 第 5 节把 62、63 号符号换成 - 和 _,其余 62 个符号完全一致,也没有版本号或自动识别机制。含 + 的串丢进标准解码器会被当成非法字符,反过来含 - 的串丢进标准解码器也一样。MIME 折行则来自 RFC 2045:base64 正文单行不得超过 998 个字符,推荐每 76 个字符后插入 CRLF,本页默认宽度就取 76。
完整示例(数值仅作演示)
示例条件与页面打开时的默认状态完全一致:输入框四行原文、勾选「按 UTF-8 转字节再编码」、不勾 URL-safe、不折行。四行实测结果如下:
- 第 1 行
A:UTF-8 下 1 字节,余 1 字节 → 补 2 个=,输出QQ==(4 字符); - 第 2 行
AB:2 字节,余 2 字节 → 补 1 个=,输出QUI=(4 字符); - 第 3 行
ABC:3 字节,余 0 字节 → 无填充,输出QUJD(4 字符); - 第 4 行
柳泉工具A:4 个汉字各 3 字节加 1 个 ASCII 字母,共 13 字节,余 1 字节 → 补 2 个=,输出5p+z5rOJ5bel5YW3QQ==(20 字符)。
四行原文字节合计 1+2+3+13 = 19 字节,输出字符合计 4+4+4+20 = 32 字符,填充合计 2+1+0+2 = 5 个。逐行核算:4×ceil(1/3)=4、4×ceil(2/3)=4、4×ceil(3/3)=4、4×ceil(13/3)=20,四个数加起来正好 32。第 4 行再把字节拆开看:E6 9F B3 E6 B3 89 E5 B7 A5 E5 85 B7 41,前三字节 E6 9F B3 就是汉字「柳」的 UTF-8 编码,最后一字节 41 是大写字母 A。
把这 19 字节当作一整块连续数据编码,只需要 4×ceil(19/3) = 28 个字符;按行独立编码却输出了 32 个字符,多出来的 4 个字符就是四行末尾各自补齐 = 的开销。如果你在意长度,把多行合并成一行再编码能省下这部分。
输入原文与编码结果对照表
下表覆盖本工具最常见的几类输入。注意「输出字符数」一列只跟字节数有关,跟原文看起来长短无关;汉字一个字 3 字节、ASCII 一个字符 1 字节、emoji 一个 4 字节,混在一起凭肉眼估一定估错。
| 输入原文 | UTF-8 字节数 | 输出字符数 | 末尾填充 | Base64 结果 |
|---|---|---|---|---|
A | 1 | 4 | 2 个 = | QQ== |
AB | 2 | 4 | 1 个 = | QUI= |
ABC | 3 | 4 | 无 | QUJD |
ABCD | 4 | 8 | 2 个 = | QUJDRA== |
12345 | 5 | 8 | 1 个 = | MTIzNDU= |
123456 | 6 | 8 | 无 | MTIzNDU2 |
柳 | 3 | 4 | 无 | 5p+z |
柳泉 | 6 | 8 | 无 | 5p+z5rOJ |
柳泉工具 | 12 | 16 | 无 | 5p+z5rOJ5bel5YW3 |
柳泉工具A | 13 | 20 | 2 个 = | 5p+z5rOJ5bel5YW3QQ== |
🎉(单个 emoji) | 4 | 8 | 2 个 = | 8J+OiQ== |
Hello | 5 | 8 | 1 个 = | SGVsbG8= |
柳泉工具B | 13 | 20 | 2 个 = | 5p+z5rOJ5bel5YW3Qg== |
| 一个半角空格 | 1 | 4 | 2 个 = | IA== |
1 | 1 | 4 | 2 个 = | MQ== |
输入范围、边界与精度说明
- 单次输入上限 20 万字符。按 4/3 膨胀,20 万字符原文最多编出约 26.7 万字符,结果区再大就会明显卡顿。更长的内容请按行拆成几批,或改成整段一行再编码以省下填充开销。
btoa()的码点上限是 255,不是 127。拉丁字母、数字、常见西欧重音字母都在范围内,能直接通过;中文、日文、韩文、俄文和 emoji 一律超出。emoji 尤其要注意:一个 emoji 在 UTF-16 里是两个码元,两个码元都大于 255,所以无论怎么处理都必须先走 UTF-8 字节。- 折行宽度限 4~998 的整数。上限 998 来自 RFC 2045 对 base64 正文行长度的硬限制,下限取 4 是因为一组正好 4 个字符,再窄就连一组都放不下;推荐值 76 是 RFC 2045 的原文建议。
- URL-safe 只换两个符号,不影响长度。换表后输出字符数完全不变,只是把
+与/分别写成-与_。例如柳泉的标准结果是5p+z5rOJ,URL-safe 版本是5p-z5rOJ,只有第 3 个字符不同。 - 逐行编码与整段编码是两个不同的结果。本页按行处理,每行独立补齐;如果业务方要求的是「整段字节流编码」,请先把换行去掉、合并成一行,否则不仅填充个数不同,连编码出来的字符串都不一样。
- Base64 不是压缩也不是加密。它只做表示形式的转换,体积只增不减,任何人拿到字符串都能立刻还原。把敏感字段做一次 Base64 就以为别人看不见,是本页最常见的误用。
- 填充只出现在末尾且最多 2 个。如果业务方明确要求「不带填充」的变体(部分 JWT 实现就是这么做的),本页不提供省略填充的开关,避免生成一个标准解码器不一定认的串——这类需求正确做法是改用 URL-safe 表并按对方的规则处理。
常见问题
为什么中文丢进去会报「字符超出 Latin-1 范围」?
因为 btoa() 按 HTML 标准只接受每个码点都不超过 255 的字符串。汉字 柳 的码点是 U+67F3(十进制 26611),远远超标,浏览器只能抛错。勾上「按 UTF-8 转字节再编码」,工具会先用 TextEncoder 把它编成 E6 9F B3 三个字节再交给 btoa(),问题就消失了。
为什么编码后比原文长了三分之一?
因为每个 6 位都要占一个完整字符。3 字节 = 24 位,拆成 4 个 6 位正好 4 个字符,所以长度是 4 × ceil(n / 3),比值恒为 4/3。这是 Base64 的本质代价,不是实现缺陷——它换来的是「输出只含 64 个可打印 ASCII 符号」这个性质。
末尾的 = 可以手动删掉吗?
技术上很多解码器能自动补回来,但标准里 = 是编码结果的一部分,删掉之后这串字符在严格校验的场景(例如签名比对、长度断言)就会对不上。要求不带填充的场合(比如某些 JWT 实现)应当整体改用 URL-safe 字母表并按对方的规则处理,而不是随手删符号。
同一段文字,为什么我和同事编出来的结果不一样?
三种可能:一是勾选的选项不同(URL-safe、折行都会改变输出);二是原文末尾多带了空格或换行;三是他那边先做了别的处理再编码。换行最容易出错——Windows 记事本默认 CRLF,编辑器和网页表单多给 LF,两者差一个 0x0A 字节,编出来自然不同。
把编码结果放进网址参数后,服务端收到的内容变了?
大概率是 + 被当成空格了。查询串默认按 application/x-www-form-urlencoded 解析,其中的 + 会被还原成空格,标准字母表里的 + 正好中招。改成勾选「输出 URL-safe 字母表」把 + 换成 -,或者让调用方对整串再做一次百分号编码。
折行用 LF 还是 CRLF?
本页按 RFC 2045 的约定输出 CRLF(0x0D 0x0A),这是 MIME 正文的标准行结束符。如果目标系统明确要求 LF,可以折行导出之后自行替换,或者干脆不折行、交给对方处理。折行只是排版,不影响解码结果——按 RFC 4648 第 3 节,解码时本来就应该忽略换行与空白。
编码结果能当密文用吗?
不能。Base64 是编码不是加密,没有密钥、没有混淆,任何人拿到字符串都能反着算回原文。它唯一的「保护」是让内容看起来不像明文,这在安全上没有任何意义。要保密请用真正的加密算法,并把密钥和密文分开存放。
输入的内容会不会被上传?
不会。字节转换、字母表查表、填充补齐、折行全部在页面里完成,没有任何网络请求,也不写浏览器存储。想自己确认,打开开发者工具的 Network 面板连点几次「开始编码」,可以看到没有新请求发出。
相关工具
- Base32解码:反向操作另一种 32 符号字母表,每组 8 个字符换 5 字节,常用于一次性密钥。
- Base32编码:同一个族的正向编码,字母表只有 32 个符号且不含数字
0/1/8/9,适合需要人工念读的场合。 - URL编码:把中文和保留字符转成
%E6%9F%B3这样的百分号转义,和 Base64 是两种不同的「变成 ASCII」路线。 - HTML实体编码:把
&、<这类字符转成 HTML 实体,处理网页源码时用得上。 - 文本转十六进制转换器:看字节最直接的方式,能把
柳展开成E6 9F B3,用来核对本页的中间结果。 - 文本转二进制:展开成
01000001这种 0 和 1,能直观看到本页「24 位拆成 4 个 6 位」是在切哪一段。 - JWT编码:令牌把三段 Base64 拼在一起并追加签名,单独用本页只会得到其中一段。
- 编码解码:查看全部编码解码工具。