二进制转文本:解码字节,以及知道什么时候解不出来
这个换算在做什么
它把一串二进制字节读出来,按 UTF-8 解码成文本。八位构成一个字节,然后这些字节要一起解码,因为一个字符可能占好几个字节。真正的功夫在解码这一步:字节边界完全不会告诉你字符边界在哪里。
解码器怎么知道字符到哪结束
每个字节的前导位会说明自己的角色。以 0 开头的字节自成一体,以 110 开头的开启一个两字节字符,1110 开启三字节字符,11110 开启四字节字符,而续字节都以 10 开头。正是这个结构让解码器不必被告知字符位置就能走完整个字节流,也正是它让一处切错位置的字节流能够被检测出来。
二进制转文本对照表
字节序列及其解码出的文本。多字节那几行展示了前导位模式的实际作用,最后一行则显示一段并非可打印文本的原始字节是什么样子。
| 二进制 | 文本 |
|---|---|
| 01000001 | A |
| 01100001 | a |
| 01001000 01101001 | Hi |
| 01001111 01001011 | OK |
| 00110001 00110010 00110011 | 123 |
| 11100100 10111000 10101101 | 中 |
乱码是怎么产生的
乱码几乎总是意味着字节用错了编码,或者在错误的偏移处被切开。把 UTF-8 当成单字节编码来解码,一个三字节字符会变成三个毫不相干的符号;从头丢掉一个字节,后面每一个字符都会整体错位。两种故障看起来都像随机的符号,而都要靠看字节而不是看字符来诊断。
保持字节分组完整
请复制完整的八位一组。从某个字节中间开始粘贴,会得到一个解码器无法理解的序列,随之而来的报错是准确的,但不会明显指向你粘贴的起点在哪里。
常见问题
怎样把二进制解码回文本?
把二进制按八位一组切开,每组当作一个字节,再把这些字节按 UTF-8 解码。字母 A 是 01000001,所以一组正好解出一个字符;序列更长就解出更长的字符串,其中有些字符会跨好几组。
为什么我得到的是报错而不是奇怪的字符?
因为这串字节不是合法的 UTF-8——可能被截短了、顺序错了,或者根本不是文本。拒绝它是刻意的:另一种做法是替换成替代字符,那样输出的东西看起来像解码出了问题,而真正的问题其实是这些字节从来就不是文本。
可以粘贴字节之间没有空格的二进制吗?
可以。长度是 8 的倍数的连续串会被自动切成字节,所以从不带分隔符的来源复制来的二进制不必先重排格式。带空格和不带空格的两种形式含义完全相同。
单独一个大于 127 的字节是什么意思?
说明它属于某个多字节字符,而不是一个独立的字符。这个范围内孤零零的一个字节没有合法的 UTF-8 含义,会被拒绝,而这是正确的处理方式——它所属的那个字符并不完整。
任何语言的文本都能处理吗?
能,只要是 UTF-8 能表示的都行,也就是当前在用的几乎所有书写系统,包括带音标的拉丁字母、西里尔字母、阿拉伯文、中文、日文、韩文和 emoji。本站文本转二进制工具生成的序列,一定能原样解回你最初输入的文本。