全部文章

为什么中文和日文标签会变成 ÖܽÜÂ×,以及怎样一次性修好

你把攒了十五年的曲库搬到新设备上,打开一看,三分之一的艺人名变成了 ÖܽÜÂ× 和 ³¯«³¨³。文件没坏,数据也没丢——你只是在用错误的解码器看正确的字节。

你看到的到底是什么

硬盘上的文字就是字节。要把字节还原成字符,必须知道它当初是用哪种编码写的。这个信息一旦缺失,播放器就只能猜,而历史上的默认猜测是 Latin-1——它把全部 256 个字节值都映射到某个字符,所以永远不会报错,只会安静地给出一堆乱码。

同一个名字的三种写法:

原文 编码 字节 按 Latin-1 读出来
周杰伦 GBK D6 DC BD DC C2 D7 ÖܽÜÂ×
陳奕迅 Big5 B3 AF AB B3 A8 B3 ³¯«³¨³
椎名林檎 Shift-JIS 92 C5 96 BC 97 D1 8C E7 <0x92>Å<0x96>¼<0x97>Ñ<0x8c>ç

字节是完好的,丢的是那个「这是什么编码」的标签。

编码信息是怎么丢的

这取决于标签格式,而且区别很关键:

  • ID3v1 根本没有编码字段。每个字段是固定 30 字节的原始字节槽,没有任何地方能记录「这是 GBK」。
  • ID3v2.3 有编码字节,但只给两个选项:0x00 表示 ISO-8859-1,0x01 表示 UTF-16。当年的中文、日文打标签软件两个都不想用,于是把 GBK 或 Shift-JIS 的字节直接塞进一个声明为 ISO-8859-1 的帧里。文件上写着 Latin-1,但它在撒谎。
  • ID3v2.4 才加上 UTF-8(0x03),所以大约 2010 年以后打的标签通常没问题。
  • APEv2(.ape、.wv 用的)在规范里明确要求 UTF-8。这里出乱码说明打标签的软件没守规范。
  • Vorbis comment(FLAC 和 Ogg 用的)同样强制 UTF-8。如果你的 FLAC 标签乱码,那几乎一定是从已经坏掉的源转码过来的,而不是在原地写错的。

所以常见情况其实很具体:一首 2000 年代在中国大陆、台湾或日本的 Windows 上打过标签的 MP3——系统代码页默默提供了编码,而文件本身从没记下来。

怎么分辨是哪种编码

肉眼基本就能认出来:

  • 满屏 Ö Ü ½ Â × 这类带音标的大写字母——GBK。GBK 的汉字首字节大多落在 B0–F7,正好对应 Latin-1 里的带音标大写字母。
  • 带音标字母里夹着正常的 ASCII 大写字母,比如 ¾HÄR§g——Big5。Big5 的第二字节经常落在 ASCII 区间,所以乱码中间会冒出真正的英文字母。
  • 不可打印的方块和音标字符交替出现——Shift-JIS。它的首字节包含 0x81–0x9F,而 Latin-1 在这段区间里放的是没有字形的控制字符。

如果字符串里出现了 ``(U+FFFD,替换字符),就别猜了——这种情况不一样,下面会说。

只改显示不叫修好

不少播放器允许你手动指定「按 GBK 解读」。这能解决那一个播放器、那一台设备上的症状。文件里的字节一个都没变,所以你换个播放器、或者重装一次,它又会从头开始猜。

真正管用的修复是在文件上做一次往返:

  1. 把乱码字符串按 Latin-1 编码回字节,拿回原始字节序列;
  2. 用真正产生它的编码去解码——GBK、Big5、Shift-JIS;
  3. 把修正后的文字写回标签,用 UTF-8,并且写进一个如实声明 UTF-8 的帧里。

第 3 步是大多数人省掉的一步,也正是它让修复变成永久的、可迁移的。做完之后文件自己带着编码信息,换任何播放器都不用再猜。

Sovault 是三步一起批量做的:自动识别可能的源编码,先给出修正后的预览让你确认,确认无误再写回文件。预览这一步很重要——编码识别本质是启发式判断,某些字节序列用 Big5 和 GBK 解码都能得出看起来合理但并不相同的结果。

哪些情况是真的救不回来

有两种确实修不了,知道了能省你一下午:

被截断的 ID3v1 字段。 那些槽位恰好是 30 字节。15 个汉字在 GBK 下正好 30 字节、刚好塞满;第 16 个字会被从中间切断,后半个字节就是没了。你能恢复截断点之前的全部内容,但截断点之后的恢复不了。

已经被二次转换过的文本。 如果之前有软件「修复」过这些标签——把它们按 Latin-1 解码再存成 UTF-8——这个损伤现在是固化在文件里了。但这种其实还能救,因为 Latin-1 对全部 256 个字节值都是无损的。真正救不回来的是经过 Windows-1252 的那一趟:它有五个字节值(0x81、0x8D、0x8F、0x90、0x9D)是未定义的,碰上这几个字节的内容会被替换成 U+FFFD,原始字节彻底消失。这就是为什么看到替换字符就该停手——那说明信息被销毁了,而不只是贴错了标签。

除此之外,数据其实一直好端端地躺在那儿,只是在等一个正确的读法。