使用方法
- 在输入框里写或粘贴文字,上限 8000 字符。页面默认已填好一段 5 个字符的示例,打开就能看到转换结果,不用先点按钮。
- 选「输出格式」。默认的空格分隔最适合人工核对,也最容易按 8 位切回来;「连续 8 位串」体积最小,适合塞进紧凑的字段;「0b 前缀逗号分隔」方便直接粘进 C、Java 这类语言的数组字面量;「每字节一行」适合逐行比对十六进制清单。
- 填「每行字节数」,允许 1 到 64。默认 8,因为 8 个字节正好是 64 位,一行二进制读起来和处理器里一个 64 位字对齐。
- 点「转换为二进制」执行,或者在输入框里按 Ctrl + Enter(macOS 为 Cmd + Enter)。这个页面刻意不用裸 Enter 触发,因为 Enter 必须留给换行——文本里有没有换行会直接改变字节结果。
- 对照下面的字节表核对:偏移从 0 开始,一条记录就是一个字节,同时给出十六进制、二进制和它来自哪个字符。表默认显示 12 行,超出后点「加载更多」每次追加 24 行。
- 要带走数据,用「复制二进制结果」「复制字节表」(制表符分隔,可直接粘进表格)或「导出字节 CSV」(带 BOM,Excel 打开中文不乱码)。
这个文本转二进制工具能解决什么问题
一是看清一个字符到底占几个字节。数据库字段长度、网络报文长度、Redis 的 value 体积都以字节计,而人脑习惯按字符估算。把「你好」丢进这个文本转二进制工具,看到 6 个字节、48 位,就不会再按 2 个字符去申请 2 个字节的字段。
二是定位乱码的字节来源。一段文本存进数据库再取出来变成问号或方块,根因通常不是「编码声明写错了」,而是某一步按单字节截断了多字节字符。逐字节表会显示每个字节属于哪个字符的第几个字节——如果一个汉字只出现了「第 1/3 字节」,说明它在传输中被截断了。
三是给协议与硬件做字面量。串口指令、蓝牙特征值、嵌入式固件里的固定报文常常要写成一串二进制或十六进制常量。先在这里把文本转成二进制,再对照字节表抄成 0b 或 0x 数组,比手工算 UTF-8 可靠得多。
四是验证自己对 UTF-8 的理解。为什么 E4 BD A0 就是「你」?为什么续字节都以 10 开头?页面的表里每一行都能单独解释,适合当作编码课的对照材料。
本页不做这些事:不做任意进制互转(十进制、十六进制与二进制的数值互换请用「十进制转二进制转换器」),不做 Base64 或压缩,不做加密,也不做 GBK、Big5 这类多字节编码的转换——本页只有一种口径:UTF-8。
转换原理:UTF-8 分档与定长 8 位
第一步是编码。工具调用浏览器内置的 new TextEncoder().encode(text)。按 WHATWG Encoding Standard 的规定,TextEncoder 只有一种输出编码,就是 UTF-8;它返回一个 Uint8Array,每个元素都是 0 到 255 之间的整数。这里不用任何 ASCII 或 Latin-1 的兜底分支,因为那正是乱码的来源。
第二步是按码点遍历,而不是按 UTF-16 码元。JavaScript 的字符串以 UTF-16 存储,直接按下标循环会把一个表情读成两个「半个字符」。工具用 codePointAt(i) 取出码点,遇到大于 U+FFFF 的码点就把下标多前进一位,再用 String.fromCodePoint() 还原成完整字符,然后单独对它做一次 UTF-8 编码。这样每个字节都能准确地归属到一个字符。
第三步是定长补零。把字节写成二进制用 b.toString(2).padStart(8,'0')。padStart(8,'0') 不是装饰性的:字符 A 的字节是 0x41,二进制是 1000001,只有 7 位;如果不补零,拼出来的串长度不固定,接收端就无法按每 8 位切分还原。补齐后它是 01000001,一个字节永远对应 8 个字符。
UTF-8 的分档规则决定了每个字符占几个字节,规则按码点范围分四档:U+0000 到 U+007F 用 1 字节,首字节形如 0xxxxxxx;U+0080 到 U+07FF 用 2 字节,首字节形如 110xxxxx,后面跟 1 个 10xxxxxx;U+0800 到 U+FFFF 用 3 字节,首字节形如 1110xxxx,后面跟 2 个续字节;U+10000 到 U+10FFFF 用 4 字节,首字节形如 11110xxx,后面跟 3 个续字节。续字节一律以 10 开头,这也是为什么页面的字节表里汉字的后两个字节总是 10 打头。
汉字为什么稳定是 3 字节。CJK 统一表意文字基本区是 U+4E00 到 U+9FFF,共 20992 个码位,整段都落在 U+0800 到 U+FFFF 这一档里,所以常用汉字一律 3 字节、24 位。很多人以为一个汉字固定 2 字节,那是 GBK 的老口径:GBK 里一个汉字确实占 2 字节,但 GBK 与 UTF-8 是两套互不兼容的编码,页面的表在 UTF-8 下永远是 3 字节。
表情为什么是 4 字节。以 U+1F600 为例,它在 UTF-16 里是一对代理码元 D83D DE00,占 2 个码元、1 个码点;UTF-8 编码后的四个字节是 F0 9F 98 80。所以同一个字符,按码点数、按码元数、按字节数会得到 1、2、4 三个不同的值,这三个数在页面顶部的统计卡里分别列出。
完整示例(数值仅作演示)
示例文本就是页面输入框里的 你好 A😀:3 个汉字?不是——它由「你」「好」、一个半角空格、字母 A 和表情 😀 组成,共 5 个码点。因为表情占 2 个 UTF-16 码元,所以按码元数出来是 6;按 UTF-8 编码后是 12 个字节,也就是 96 位。逐字符的账目如下:
- 「你」U+4F60 →
E4 BD A0,3 字节; - 「好」U+597D →
E5 A5 BD,3 字节; - 半角空格 U+0020 →
20,1 字节; AU+0041 →41,1 字节;😀U+1F600 →F0 9F 98 80,4 字节。
加起来 3 + 3 + 1 + 1 + 4 = 12 字节,与统计卡一致。按默认的「空格分隔、每行 8 字节」输出,结果正好两行:第一行 8 个字节共 71 个字符,第二行 4 个字节共 35 个字符,合计 107 个字符——比原来的 5 个字符长了约 21 倍。这就是二进制表示的真实代价:每个字节被展开成 8 个可见字符,再加分隔符。
注意第 2 个字节和第 6 个字节都是 BD,但它们的归属不同:一个是「你」的第 2 字节,一个是「好」的第 3 字节。只看字节值无法反推字符,必须结合偏移和 UTF-8 的分档规则。这正是页面把「来源字符」和「第几个字节」两列同时列出来的原因。
输入范围与字符-字节对照表
第一张表是输出体积:字节数一定时,输出字符数只由分隔符和每行字节数决定,与内容无关。表里的数按「空格分隔」计算,公式是「字节数 × 8 + (字节数 − 1)个空格」。
| 输入 | UTF-8 字节数 | 二进制位数 | 输出字符数(空格分隔) |
|---|---|---|---|
| 1 个 ASCII 字符 | 1 | 8 | 8 |
| 示例「你好 A😀」 | 12 | 96 | 107 |
| 「你好」两个字 | 6 | 48 | 53 |
| 100 个 ASCII 字符 | 100 | 800 | 899 |
| 1000 个 ASCII 字符 | 1000 | 8000 | 8999 |
第二张表是常见字符的实测字节。同一张表里可以看到 1、2、3、4 四个分档同时出现,其中 〇 虽然读作「零」,但它属于中日韩符号区,UTF-8 下仍是 3 字节:
| 字符 | 码位 | UTF-8 字节 | 十六进制 | UTF-16 码元 |
|---|---|---|---|---|
| A | U+0041 | 1 | 41 | 1 |
| 0 | U+0030 | 1 | 30 | 1 |
| (空格) | U+0020 | 1 | 20 | 1 |
| é | U+00E9 | 2 | C3 A9 | 1 |
| ß | U+00DF | 2 | C3 9F | 1 |
| ø | U+00F8 | 2 | C3 B8 | 1 |
| 中 | U+4E2D | 3 | E4 B8 AD | 1 |
| 你 | U+4F60 | 3 | E4 BD A0 | 1 |
| 〇 | U+3007 | 3 | E3 80 87 | 1 |
| € | U+20AC | 3 | E2 82 AC | 1 |
| 😀 | U+1F600 | 4 | F0 9F 98 80 | 2 |
| 𠮷 | U+20BB7 | 4 | F0 A0 AE B7 | 2 |
| 𝐀 | U+1D400 | 4 | F0 9D 90 80 | 2 |
第三张表是分档的边界码位。判断一个字占几字节,只要看它落在哪一档,不需要查表:
| 码点范围 | 字节数 | 首字节形状 | 边界实测 |
|---|---|---|---|
| U+0000 – U+007F | 1 | 0xxxxxxx | U+007F 编成 1 字节 |
| U+0080 – U+07FF | 2 | 110xxxxx | U+0080 编成 2 字节,U+07FF 也是 2 字节 |
| U+0800 – U+FFFF | 3 | 1110xxxx | U+0800 编成 3 字节,U+FFFF 也是 3 字节 |
| U+10000 – U+10FFFF | 4 | 11110xxx | U+10000 编成 4 字节,U+10FFFF 也是 4 字节 |
结果边界、输入上限与舍入说明
- 输入上限 8000 字符(输入框 maxlength,按 UTF-16 码元计)。超过之后输入框不再接收新内容,已在里面的文字不会被截断,也不需要重新输入。
- 编码后字节上限 4096。这是本页最硬的一条边界,超过会直接报错并给出实际字节数,不做截断。为什么卡在这个数:4096 字节在空格分隔下会产出 36863 个字符,已经接近浏览器单段文本渲染的舒适上限;再大就会让页面明显卡顿。如果你的文本更长,请分段处理。
- 空输入会报错,不会静默输出空串。只有空白字符(空格、制表符、换行)的输入不是空输入——空白也是真实的字节,会被正常转换:一个换行是 0x0A,一个制表符是 0x09,一个空格是 0x20。
- 全程整数,没有任何舍入。字节值是 0 到 255 的整数,二进制串长度是字节数乘 8,页面不会做四舍五入、不会省略前导零、不会压缩连续的 0 或 1。
- 孤立代理会被替换成 U+FFFD。如果文本里含有一半的代理码元(例如只保留了
D83D而没有配对的DE00),按 WHATWG 编码规范它无法映射到任何码点,TextEncoder会输出替换字符的 UTF-8 字节EF BF BD,共 3 个字节。页面会在结果里照实体现,不会提示你「修复」它,因为无法知道原本想表达什么。 - 「每行字节数」只影响排版,不影响字节与位数。无论每行放 1 个还是 64 个字节,字节总数、二进制位数、CSV 内容都完全一致,它只改变结果区里换行的位置。
- 换行符本身也会被编码。输入里的
\n(LF)是 0x0A、\r\n(CRLF)是 0x0D 0x0A,不同系统的粘贴内容字节数会因此差 1 到若干字节,核对体积时要把这部分算进去。 - 输出不是压缩,而是放大。每字节膨胀成 8 个字符,加上分隔符,ASCII 文本的体积会变成原来的 8 倍多一点,中文文本约 26 倍(1 个汉字 3 字节 → 24 位加 2 个空格)。要传给别人请优先用 CSV 导出,别直接复制粘贴到聊天窗口。
常见问题
为什么「你好」两个字变成了 6 个字节?
因为 UTF-8 里一个常用汉字占 3 字节。「你」是 U+4F60,编码成 E4 BD A0;「好」是 U+597D,编码成 E5 A5 BD。两个字符加起来 6 字节、48 位。如果你的场景里一个汉字只占 2 字节,那用的是 GBK 而不是 UTF-8,本页不输出 GBK 结果。
一个汉字到底占几个字节?和 GBK 是什么关系?
取决于编码。UTF-8 下常用汉字是 3 字节(整个 CJK 基本区 U+4E00–U+9FFF 都在 U+0800–U+FFFF 这一档),GBK 下是 2 字节。两者互不兼容:同一串字节用 UTF-8 解会乱码,用 GBK 解也会乱码。现代网页、JSON、数据库大多默认 UTF-8,遇到老系统导出的文件才需要怀疑 GBK。
表情符号为什么占 4 个字节?
因为表情的码点通常在 U+1F600 这类补充平面里,超出了 UTF-16 单个码元能表示的范围。😀 在 UTF-16 里被拆成 D83D 和 DE00 两个码元,在 UTF-8 里被编成 F0 9F 98 80 四个字节。所以页面上「字符数」是 1、「UTF-16 码元」是 2、「字节数」是 4,三个数字都对,只是口径不同。
为什么每个字节一定要写成 8 位、前面补 0?
因为二进制串要能被切回来。A 的字节 0x41 直接转二进制是 1000001,只有 7 位;如果某些字节 7 位、某些 8 位,接收端就没法按固定长度切分,也无法判断 1000001 是 0x41 还是别的东西。补成 01000001 后,每 8 个字符必定是一个字节,这个约定必须由编码方保证。
输入里冒出 EF BF BD 是什么意思?
那是 Unicode 替换字符(U+FFFD,“�”)的 UTF-8 字节。出现它只有两种原因:原始文本里就含有孤立的代理码元(半个表情),或者上游某一步已经把无法解码的字节替换成了它。页面只是照实编码,不会去猜原本的内容——替换一旦发生就是不可逆的,只能回到源头重新取一次原始字节。
输出这么长,会不会复制不全?
输出区是有滚动条的容器,点击复制拿到的始终是完整字符串,与当前滚动位置无关。真正会截断你的是粘贴目标:聊天软件、Excel 单元格和部分输入框都有长度限制。需要搬运时优先用「导出字节 CSV」,一行一个字节,比整段二进制串更好处理。
空文本和只有空白的文本会输出什么?
空文本会报错并提示你输入内容,不会输出一个空结果让你以为转换成功了。只有空白的文本属于正常输入:空格是 0x20、制表符是 0x09、换行是 0x0A,它们会被逐字节转成二进制,只是很多人以为「看不见的字符不算内容」。
这和「十进制转二进制」是同一件事吗?
不是。本页做的编码:把字符按 UTF-8 映射成字节,再把字节展开成 8 位串,字符 → 字节 → 位串,中间一步是编码。进制互转做的是数值:把 2026 这个数从十进制写成二进制 11111101010,不涉及字符编码。所以「文本转二进制」用于看编码字节,「十进制转二进制」用于做数值换算,两者输入相同也可能是完全不同的结果。
相关工具
- 二进制转文本:反方向还原,把 8 位串按 UTF-8 拼回字符,与本页互为逆操作。
- 文本转十六进制转换器:同样先做 UTF-8 编码,但把每个字节写成两位十六进制,体积只有二进制表示的四分之一。
- 十六进制转文本转换器:拿到一段 hex 想还原成文字时用它,和本页的对照表配合最方便。
- 文本转ASCII转换器:只处理码点在 0 到 127 的字符,超出范围的字符按 ASCII 口径处理,与 UTF-8 口径不同。
- Unicode转义反转义工具:把字符写成 U+4E2D 或 \u4e2d 形式,查某个字的确切码位时更快。
- Base32编码:另一种把字节变成可见字符的编码,用 32 个字符表示 5 位,可作为对比理解 Base64 与二进制表示的差别。
- ASCII表生成器:查 0 到 127 的控制字符与可打印字符对照,核对字节 20、41 这类常见值时用得上。
- 编码解码:查看全部编码解码工具。