
说到软件本地化,很多人第一反应是"翻译文字"这么简单的事儿。但真干了这行才知道,光是把文字原封不动地从一种语言变成另一种语言,远远不够。我在这行摸爬滚打这些年,见过太多因为字符集问题栽跟头的案例——界面显示乱码、排序规则诡异、搜索功能失效,严重的时候整个软件干脆跑不起来。
今天我想聊聊软件本地化里最容易被忽视、但又最关键的一环:字符集要求。这不是什么高深莫测的理论,都是实打实踩坑踩出来的经验之谈。
在进入正题之前,我们先搞清楚几个基础概念。字符集,你可以理解为一套计算机用来表示文字的"密码本"。计算机其实只认识0和1,它要显示一个"中"字,就得有一套规则告诉它:这个二进制数对应的是哪个字符。
早期的字符集很简单,ASCII就规定了128个字符,足够英语用了。但全世界有那么多语言,每一个字、每一个符号都得有个对应的编码,这就催生了后来各种各样的字符集标准。
软件本地化跟字符集有什么关系?关系太大了。你想啊,把一个软件从英文本地化成中文、日文、阿拉伯文,字符集不对应的话,翻译过去的文字在目标系统上可能显示成一堆问号、方框,或者干脆是乱码。更糟糕的是,有些语言的文字走向、排序规则、字符宽度都跟英语截然不同,没有处理好字符集,软件的各种功能都会出问题。
在软件本地化领域,有几个字符集标准是必须搞清楚的。

ASCII虽然老,但它至今仍是很多系统的基础。它用7位(bit)表示128个字符,包括英文字母、数字、标点和一些控制字符。在纯英文环境下,这个够用。但一旦涉及其他语言,ASCII就力不从心了。你看,光是一个欧元符号€,ASCII就表示不了,更别说汉字、阿拉伯字母这些复杂的文字了。
Unicode的目标很宏大:收录世界上所有的字符,给每个字符分配一个唯一的编号。目前Unicode已经收录了超过14万个字符,涵盖了绝大多数人类语言,还包括表情符号、数学符号等各种符号。
在Unicode的框架下,有三种主要的编码方式:UTF-8、UTF-16和UTF-32。
UTF-8是我们最常见的,它采用变长编码,英文用一个字节,汉字通常用三个字节。它的好处是兼容ASCII,互联网上的大部分网页、文件都是UTF-8格式。而且它比较节省空间,对于以英文为主、偶尔夹杂其他语言的软件来说,UTF-8是首选。
UTF-16用两个或四个字节表示一个字符,在Windows系统和Java环境中用得比较多。它的好处是固定长度字符处理起来效率高,但对于纯英文内容来说,空间开销会比UTF-8大一些。
UTF-32最简单暴力,每个字符都用四个字节,完全等长,处理起来最快,但空间消耗也最大,实际应用中相对少见。
在康茂峰处理的本地化项目里,UTF-8几乎是我们默认的选择。它的通用性和兼容性经过这么多年实践的检验,确实没得说。但我们也遇到过一些特殊情况,比如客户的老系统只支持UTF-16,这时候就得灵活调整。

除了Unicode,各地区也发展了一些本地化的字符集标准。比如中文的GB2312、GBK、GB18030,日文的Shift-JIS,韩文的EUC-KR等等。这些字符集在特定历史时期发挥了重要作用,但现在新建的项目基本都转向Unicode了。
不过,你可能会遇到一些遗留系统,或者客户指定要求使用特定字符集的情况。这时候你得了解这些传统字符集的局限性,比如GBK收录的汉字比Unicode少,特殊符号、生僻字可能无法表示。遇到这种情况,我们通常会建议客户升级到Unicode,但如果客观条件不允许,就得在翻译过程中格外注意用字的规范性。
软件是要跑在操作系统上的,而不同操作系统对字符集的支持情况各不相同,这一点在本地化时必须考虑进去。
Windows从NT内核开始就全面转向Unicode。它的API几乎都是Unicode版本的,ANSI版本的API实际上只是在Unicode和本地代码页之间做了转换。所以如果你的软件要本地化到Windows平台,使用Unicode是最省心的做法。
Windows还维护了一套代码页(Code Page)系统,每种代码页对应一种字符集编码。比如代码页936是GBK,代码页54936是GB18030。系统在处理非Unicode程序时,会根据代码页来进行字符转换。这套机制解决了兼容性问题,但也带来了一些麻烦——不同区域的Windows可能默认代码页不同,如果程序没有正确处理 locale 设置,就可能出现乱码。
苹果系统一直对Unicode支持得很好,文件系统、应用程序层面对多语言文字的处理都很完善。macOS默认使用UTF-8编码,很多系统工具和API都假设输入是UTF-8。在苹果平台上做本地化,基本不需要担心字符集问题,只要确保你的源文件和输出文件都是UTF-8,大多数情况下都能顺利工作。
Linux世界的字符集处理依赖于glibc和 locale 配置。系统的 locale 设置决定了应用程序如何解释字符编码。Linux支持几乎所有的字符集,但需要开发者正确设置环境变量,比如LANG和LC_*系列变量。
在Linux上,我们经常遇到locale配置不正确导致的乱码问题。比如远程服务器默认是POSIX locale,不支持中文字符,SSH连接上去看中文文件就全是乱码。这种问题看似是系统配置问题,但实际上会影响到本地化工作的各个环节,从翻译到测试,都可能被它坑到。
Android和iOS都是基于Unicode的系统,开发者基本不需要操心字符集问题。但需要注意文件编码,Android在读取文件时如果不做明确指定,可能默认使用系统编码,不同设备可能有差异。iOS相对统一,Core Foundation层面的API都假设是UTF-8。
本地化过程中,字符集转换是绕不开的一步。源语言的文件要转换成目标语言的编码,翻译记忆库和术语库可能存储着不同编码的数据,翻译工具导出的结果也要确保编码正确。这每一个环节都可能出岔子。
最常见的转换错误是"半角"和"全角"的处理。日文和中文的标点符号有全角和半角之分,转换时如果处理不当,可能出现标点位置错乱、字符宽度不对的情况。用户看界面的时候,总觉得哪里别扭,却又说不上来问题在哪。
还有就是不同语言的排序规则。Unicode定义了默认的排序算法(Unicode Collation Algorithm),但各语言往往有自己的排序习惯。比如中文按拼音排序和按笔画排序,结果就完全不同。如果软件界面的列表、搜索结果排序不正确,用户体验会大打折扣。
垂直文字的处理也是一个挑战。中文竖排、日文竖排现在虽然用得少了,但在一些古籍、报刊类应用中还是会遇到。字符集本身不规定文字的显示方向,这需要字体和渲染引擎的配合。本地化时如果只关注字符编码,忽略了排版方向的适配,软件在目标市场上可能显得不专业。
说了这么多理论,我们来看看实际工作中应该怎么控制字符集。
在项目启动阶段,首先要确认目标语言的字符集要求。大多数情况下,UTF-8是标准答案,但如果有特殊规定,一定要提前记下来,写进项目文档里。这个环节康茂峰的项目经理都会跟客户反复确认,宁可多沟通几次,也不要等到后期发现问题再返工。
翻译人员在处理源文件的时候,要注意文件的原始编码。有些客户发来的文件可能是GBK编码的,如果直接用UTF-8去读,中文部分就会乱码。我们的翻译团队通常会先用专业工具检测文件编码,确保万无一失之后再开始翻译。
翻译工具的选择也很重要。主流的计算机辅助翻译工具都支持多编码,但不同工具的处理能力有差异。我们会选择那些对Unicode支持完善、能自动检测编码、转换过程有日志记录的工具。这样即使出了问题,也能快速定位原因。
术语库和翻译记忆库的统一编码管理是容易被忽视的一环。如果你的TM库里有不同编码的历史数据,混合使用的时候会出乱码。我们会定期检查和维护TM库,确保所有数据都是统一的UTF-8编码,避免低级错误影响翻译效率。
基于多年的实战经验,我总结了几个字符集相关的高频问题及其排查思路。
| 问题现象 | 可能原因 | 排查方向 |
| 翻译文字显示为问号 | 目标编码不支持该字符,或转换时丢失 | 检查源文件编码、目标编码、转换工具设置 |
| 文字显示为方框或乱码 | 字体不支持,或编码识别错误 | 检查系统字体、文件实际编码、编辑器设置 |
| 排序结果不正确 | 使用了默认的字节排序,而非语言特定排序 | 检查排序算法配置、语言locale设置 |
| 搜索功能失效 | 索引和查询使用了不同编码 | 检查数据库编码、搜索组件配置 |
遇到这类问题,我的建议是先"断网"——不要猜,用工具去看文件的实际编码。Linux下可以用file命令,Windows下可以用记事本的"另存为"查看编码,或者用十六进制编辑器直接看字节序列。很多时候,问题解决不了,是因为我们连真正的编码是什么都没搞清楚。
说了这么多,我想分享几点个人的感悟。
第一,字符集问题往往是"平时不出事,出事要人命"。平时翻译流程顺利的时候,你可能觉得编码处理是小事。但一旦出问题,比如软件上线前夜发现所有德语特殊字符都显示异常,那真是要急得跳脚。所以与其事后补救,不如事前做好规范。
第二,多学一点底层原理没有坏处。知道ASCII、Unicode、UTF-8之间的关系,知道为什么要有这些标准,遇到问题的时候你才能举一反三。我见过很多译者,翻译水平很高,但对计算机基础一窍不通,出了问题完全不知道从何入手。反过来,也有些技术人员懂编码但不懂翻译,理解不了为什么一个简单的字符会导致整个句子不通顺。最好的状态是两方面都懂一些,沟通起来不费劲。
第三,工具要用对。好的翻译工具、好的编码检测工具、好的编辑器,能省很多事。康茂峰在选择工具链的时候,一直把编码处理能力作为重要考量因素。工具选对了,效率能高一倍不止。
第四,遇到不确定的情况,多问多做记录。编码问题有时候很隐蔽,同一个文件在不同机器上表现可能不一样。你以为是UTF-8,其实可能是UTF-8 with BOM;你以为系统支持某个字符,其实字体库里没有。遇到这种坑,记下来,下次就能避开了。
软件本地化是个系统工程,字符集只是其中一个环节,但它像地基一样重要,地基不牢,上面盖什么都会出问题。
这些年技术发展了,Unicode越来越普及,字符集问题不像以前那么让人头疼了,但新的挑战也随之而来——表情符号的处理、变体序列的显示、不同平台emoji表现不一致,这些新问题又需要我们持续学习。
如果你刚入行,建议把字符集这关好好过一下。不用研究得多深,但基本的概念、常见的坑、排查的方法,这些得心中有数。等你真正遇到问题的时候,就不会慌了。
