📚 开源资源分享——颜佐光的个人书架
✉️ 联系站长
书架 / go / 语法

go语言判断文件是否为UTF8编码

2020-08-09 11:57 · 约 1,169 字 · 浏览 2,636 次语法

go语言判断文件是否为UTF8编码

一、思路:

  1. UTF8编码规则:
    - 对于单字节字符,8个比特位最高位为0
    - 对于多字节字符,若字符由n个字节组成,则第一个字节8个比特中最高n位都是1,剩下n-1字节中最高位都是10
  2. 读取文件得到字节流
  3. 判断是单字节字符还是多字节字符
  4. 定义计数器nBytes,遍历每个字节,将字节与0x80进行与运算判断,结果为0,单字节字符,没毛病。结果不为0,用nBytes记录最高位出现的1的个数,然后判读剩下n-1个字符最高位是否10,将n-1字节分别与0xc做与运算,若有一个不满足直接返回false,否则每次nBytes--,最后根据nBytes是否为0判断是否为U8编码。

二、代码实现

package main

import (
    "io/ioutil"
    "fmt"
)

func validUTF8(buf []byte) bool{
    nBytes := 0
    for i:= 0;i<len(buf);i++{
        if nBytes == 0{
            if (buf[i] & 0x80) != 0 {  //与操作之后不为0,说明首位为1
                for (buf[i] & 0x80) != 0 {
                    buf[i] <<= 1 //左移一位
                    nBytes++ //记录字符共占几个字节
                }

                if nBytes < 2 || nBytes > 6 { //因为UTF8编码单字符最多不超过6个字节
                    return false
                }

                nBytes-- //减掉首字节的一个计数
            }
        }else{ //处理多字节字符
            if buf[i] & 0xc0 != 0x80{ //判断多字节后面的字节是否是10开头
                return false
            }
            nBytes--
        }
    }
    return nBytes == 0
}
func main(){
    b,err := ioutil.ReadFile(`test.txt`)
    if err != nil{
        fmt.Println(err)
    }
    fmt.Println(validUTF8(b))
}

三、测试

1
返回 true
2
返回 false

← 返回《go》目录书架 →