[golang]一个复杂的中文编码问题

今天在网上遇到一个问题,觉得挺有意思,就帮人解答了。

需求

在编码为Latin1的MySQL数据库中插入中文数据,由另一个系统将Latin1编码的字符串转码为GBK后作为短信内容发出。

简单版解答

import (
    "golang.org/x/text/encoding/charmap"
    "golang.org/x/text/encoding/simplifiedchinese"
)

func Convert(src string) (string, error) {
    gbk, err := simplifiedchinese.GBK.NewEncoder().Bytes([]byte(src))
    if err != nil {
        return "", err
    }
    latin1, err := charmap.ISO8859_1.NewDecoder().Bytes(gbk)
    if err != nil {
        return "", err
    }
    return string(latin1), nil
}

解析

Latin1即ISO-8859-1,抄一段介绍 ,详见百度百科

因为ISO-8859-1编码范围使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。换言之,把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。这是个很重要的特性,MySQL数据库默认编码是Latin1就是利用了这个特性。ASCII编码是一个7位的容器,ISO-8859-1编码是一个8位的容器。

首先说一下处理编码问题的原则:保证写和读都使用同一套规则

依照这个原则处于中间环节的数据库不支持中文的问题怎么处理,要先看对方系统怎么读数据:
将Latin1编码的字符串转码为GBK后作为短信内容
那么我们任务就是:
将短信内容以GBK编码强制转码为ISO-8859-1然后存入数据库
清楚了任务,后面就是实现了。

  1. UTF8->GBK,Golang是UTF8编码的,那么首先转码GBK。这里需要注意的一点是不能用Encoder.String()方法,因为这样会强制将已经编码的GBK字节流用Golang内置的UTF8 Decoder解码,而这样得到的乱码string将无法还原回原本的GBK字节流。

  2. GBK字节流强制转ISO-8859-1字节流,怎么做呢?就是什么都不做。。。

  3. ISO-8859-1字节流->UTF8 string,我不是很确定如何在SQL中提交[]byte,那么一个保守的做法就是先将ISO-8859-1转码为UTF8,然后由数据库驱动将UTF8转回ISO-8859-1提交。

还有一点可以提一下,由于ISO-8859-1不支持中文,所以直接提交UTF8中文,数据库驱动会直接将中文替换为?。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 编码问题一直困扰着开发人员,尤其在 Java 中更加明显,因为 Java 是跨平台语言,不同平台之间编码之间的切换...
    x360阅读 7,243评论 1 20
  • 为什么要编码 不知道大家有没有想过一个问题,那就是为什么要编码?我们能不能不编码?要回答这个问题必须要回到计算机是...
    艾小天儿阅读 17,814评论 0 2
  • 主要内容 1. 字符编码理论简述 本文主要是围绕Web开发中涉及到的中文编码这一常见问题展开,包括了对字符编码基础...
    topgunviper阅读 14,702评论 5 28
  • 顶果钦哲仁波切开示 心犹如相续的河流,假如你无法运用你的修持来把握它的每个当下,你做的持咒,观想,念诵,禅修,乃至...
    Zhenzen阅读 3,890评论 0 0
  • 朱颜残灯聊赖, 墙头荒草摇曳。 荒唐少年时, 莫言生死醉。 归去 、 归去, 那得白日贪睡? 细雨落叶入微, 白衣...
    箫依行阅读 1,436评论 0 0

友情链接更多精彩内容