朋友翻出十年前的 QQ 空间,想把签名改回当年那种火星文,找了几个在线转换器,转出来一半是问号。他让我帮忙写个本地的,跑起来才发现问题不在规则。
这类转换器本质是一张字符映射表加逐字替换,真正坑人的是生僻字能不能显示。
映射表怎么建
常见的规则有几类:同音字替换,把「你」换成「伱」;偏旁拆分,把「爱」写成「愛」再加符号;还有形近字替换和颜文字拼接。整理成 JSON,左边是常用字,右边是候选数组,每次转换随机取一个,输出才不像模板刷出来的。
生僻字和扩展区
- 基本区两万多字,转换器用的多是这一片
- 扩展 B 区有六万多字,很多字体不支持,转出来是方框
- 页面统一声明 UTF-8,数据库字段也要 utf8mb4,否则存进去就丢
代码就一段替换循环
JS 里把映射表建成对象,逐字查表,查不到原样输出,最后拼成字符串。别用正则整体替换,同音字一对多,正则会互相覆盖。需要保留原文时,先用占位符把字母数字抽出来,转完再塞回去。
为什么在线工具转出来是问号
多数是页面编码和接口编码不一致。前端 UTF-8 提交,后端按 GBK 解,生僻字直接变成替换字符。还有的站点把结果塞进 URL 参数,浏览器对非 ASCII 字符的编码处理各不相同,复制出来就乱。
更要紧的是别乱用
火星文放在昵称、签名里无伤大雅,放进正文会影响搜索和阅读。做站的人拿它批量生成标题,被搜索引擎判成低质内容的例子不少。
批量生成时怎么不重样
一次转换整段文字,同一个字每次都取同一个候选,看着像机器翻的。改成按位置取模或者按随机种子取,同一篇里同一个字的写法也要有变化。生成完再做一遍去重,连续三个字都是同音替换的,读起来特别假。
朋友那个工具一下午就写完了,映射表两百多条,够用。真正的工程量在收集那些字,写代码反倒是最省事的一步。