为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
Go

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

需求

在编码为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中文,数据库驱动会直接将中文替换为?。



作者:一桶冷水
链接:https://www.jianshu.com/p/fa3ca8148d79

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消