虽然golang里面的默认编码都是统一的unicode utf8编码, 但是我们在调用外部系统提供的api时,就可能会遇到别人的接口提供的编码非 utf8编码,而是gbk/gb2312编码, 这时候我们就必须要将别人的gbk编码转换为go语言里面的默认编码utf8。
字符编码转换基础原理解析
要对编码进行转换,我们就需要知道go语言里面的字符表示形式,在go语言里面,任何的字符都是通过类型byte(也就是类型 uint8 )来进行表示的, 即任何的字符在go语言里面最终都会被转换为对应的byte数字。 而同一个字符,不同的编码方式,他们对应的数字是不一样的。 我们的编码转换实际上也很简单,我们只需要先了解某个编码他们所表示的数字范围后即可很轻松的进行转换。
GBK UTF8字符,字符串相互转换函数
// gbk to utf8 encoding conversion
func GbkToUtf8(s []byte) ([]byte, error) {
reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GBK.NewDecoder())
d, e := io.ReadAll(reader)
if e != nil {
return nil, e
}
return d, nil
}
// utf8 to gbk encoding conversion
func Utf8ToGbk(s []byte) ([]byte, error) {
reader := transform.NewReader(bytes.NewReader(s), simplifiedchinese.GBK.NewEncoder())
d, e := io.ReadAll(reader)
if e != nil {
return nil, e
}
return d, nil
}
// 字符串编码 gbk到utf8转换
func StrGbkToUtf8(str string) (string, error) {
data, err := GbkToUtf8([]byte(str))
return string(data), err
}
// 字符串编码 utf8到gbk转换
func StrUtf8ToGbk(str string) (string, error) {
data, err := Utf8ToGbk([]byte(str))
return string(data), err
}
是否GBK/GB2312编码字符、字符串判断函数
// 判断数据是否是gbk编码
func IsGbkData(data []byte) bool {
length := len(data)
var i int = 0
for i < length {
// // ASCII 编码的范围: 十进制 => 0 - 127 。 十六进制: 0x00 - 0x7F 。
if data[i] <= 127 {
i++
continue
} else {
// GB2312编码的范围: 十进制 => 高位字节:161 - 247, 十六进制:0xA1 - 0xF7
// 低位字节:161 - 254 , 十六进制:0xA1 - 0xFE
if data[i] >=129 &&
data[i] <= 254 &&
data[i+1] >= 64 &&
data[i+1] <= 254 &&
data[i+1] <= 247 {
i += 2
continue
} else {
return false
}
}
}
return true
}
// 判断字符串是否是gbk编码
func IsGbkStr(str string) bool {
if str == "" {
return false
}
return IsGbkData([]byte(str))
}
使用方法
- 安装依赖: go get github.com/tekintian/go-str-utils
- 使用示例:
package main
import (
strutils "github.com/tekintian/go-str-utils"
)
func main() {
// gb2312测试数据
gb2312Data := []uint8{10, 10, 10, 10, 10, 123, 34, 105, 112, 34, 58, 34, 49, 49, 50, 46, 49, 49, 55, 46, 55, 53, 46, 57, 57, 34, 44, 34, 112, 114, 111, 34, 58, 34, 212, 198, 196, 207, 202, 161, 34, 44, 34, 112, 114, 111, 67, 111, 100, 101, 34, 58, 34, 53, 51, 48, 48, 48, 48, 34, 44, 34, 99, 105, 116, 121, 34, 58, 34, 192, 165, 195, 247, 202, 208, 34, 44, 34, 99, 105, 116, 121, 67, 111, 100, 101, 34, 58, 34, 53, 51, 48, 49, 48, 48, 34, 44, 34, 114, 101, 103, 105, 111, 110, 34, 58, 34, 34, 44, 34, 114, 101, 103, 105, 111, 110, 67, 111, 100, 101, 34, 58, 34, 48, 34, 44, 34, 97, 100, 100, 114, 34, 58, 34, 212, 198, 196, 207, 202, 161, 192, 165, 195, 247, 202, 208, 32, 181, 231, 208, 197, 34, 44, 34, 114, 101, 103, 105, 111, 110, 78, 97, 109, 101, 115, 34, 58, 34, 34, 44, 34, 101, 114, 114, 34, 58, 34, 34, 125, 10, 10, 10, 10}
if strutils.IsGbkData(gb2312Data) {
// gbk编码的数据,需要进行转换为utf8
utf8Data, err := strutils.GbkToUtf8(bytes)
if err != nil {
// 转换失败。。。。
}
// 转换成功 这里 utf8Data 就是utf8编码的数据了
}
}