https://blog.csdn.net/tianshi418/article/details/105194869/

    1. func isGBK(data []byte) bool {
    2. length := len(data)
    3. var i int = 0
    4. for i < length {
    5. if data[i] <= 0x7f {
    6. //编码0~127,只有一个字节的编码,兼容ASCII码
    7. i++
    8. continue
    9. } else {
    10. //大于127的使用双字节编码,落在gbk编码范围内的字符
    11. if data[i] >= 0x81 &&
    12. data[i] <= 0xfe &&
    13. data[i + 1] >= 0x40 &&
    14. data[i + 1] <= 0xfe &&
    15. data[i + 1] != 0xf7 {
    16. i += 2
    17. continue
    18. } else {
    19. return false
    20. }
    21. }
    22. }
    23. return true
    24. }
    25. //UTF-8编码格式的判断
    26. func preNUm(data byte) int {
    27. var mask byte = 0x80
    28. var num int = 0
    29. //8bit中首个0bit前有多少个1bits
    30. for i:=0; i < 8; i++ {
    31. if (data & mask) == mask {
    32. num++
    33. mask = mask >> 1
    34. } else {
    35. break
    36. }
    37. }
    38. return num
    39. }
    40. func isUtf8(data []byte) bool {
    41. i := 0
    42. for i < len(data) {
    43. if (data[i] & 0x80) == 0x00 {
    44. // 0XXX_XXXX
    45. i++
    46. continue
    47. } else if num := preNUm(data[i]); num > 2 {
    48. // 110X_XXXX 10XX_XXXX
    49. // 1110_XXXX 10XX_XXXX 10XX_XXXX
    50. // 1111_0XXX 10XX_XXXX 10XX_XXXX 10XX_XXXX
    51. // 1111_10XX 10XX_XXXX 10XX_XXXX 10XX_XXXX 10XX_XXXX
    52. // 1111_110X 10XX_XXXX 10XX_XXXX 10XX_XXXX 10XX_XXXX 10XX_XXXX
    53. // preNUm() 返回首个字节的8个bits中首个0bit前面1bit的个数,该数量也是该字符所使用的字节数
    54. i++
    55. for j := 0; j < num - 1; j++ {
    56. //判断后面的 num - 1 个字节是不是都是10开头
    57. if (data[i] & 0xc0) != 0x80 {
    58. return false
    59. }
    60. i++
    61. }
    62. } else {
    63. //其他情况说明不是utf-8
    64. return false
    65. }
    66. }
    67. return true
    68. }
    69. import "golang.org/x/text/encoding/simplifiedchinese"
    70. simplifiedchinese.GBK.NewEncoder().Bytes() //utf-8 转 gbk
    71. simplifiedchinese.GBK.NewDecoder().Bytes()
    72. const (
    73. GBK string = "GBK"
    74. UTF8 string = "UTF8"
    75. UNKNOWN string = "UNKNOWN"
    76. )
    77. //需要说明的是,isGBK()是通过双字节是否落在gbk的编码范围内实现的,
    78. //而utf-8编码格式的每个字节都是落在gbk的编码范围内,
    79. //所以只有先调用isUtf8()先判断不是utf-8编码,再调用isGBK()才有意义
    80. func GetStrCoding(data []byte) string {
    81. if isUtf8(data) == true {
    82. return UTF8
    83. } else if isGBK(data) == true {
    84. return GBK
    85. } else {
    86. return UNKNOWN
    87. }
    88. }
    89. func main() {
    90. str := "月色真美,风也温柔,233333333,~!@#" //go字符串编码为utf-8
    91. fmt.Println("before convert:", str) //打印转换前的字符串
    92. fmt.Println("coding:", GetStrCoding([]byte(str))) //判断是否是utf-8
    93. gbkData, _ := simplifiedchinese.GBK.NewEncoder().Bytes([]byte(str)) //使用官方库将utf-8转换为gbk
    94. fmt.Println("gbk直接打印会出现乱码:", string(gbkData)) //乱码字符串
    95. fmt.Println("coding:", GetStrCoding(gbkData)) //判断是否是gbk
    96. utf8Data, _ := simplifiedchinese.GBK.NewDecoder().Bytes(gbkData) //将gbk再转换为utf-8
    97. fmt.Println("coding:", GetStrCoding(utf8Data)) //判断是否是utf-8
    98. fmt.Println("after convert:", string(utf8Data)) //打印转换后的字符串
    99. }