【发布时间】:2020-06-13 04:24:39
【问题描述】:
https://github.com/google/codesearch/blob/master/index/write.go#L581
我看上面是为了测试两个字节是否可以出现在一个有效的 UTF8 字符串中。但我不明白它是如何工作的。谁能帮我理解为什么这个功能有效?谢谢。
【问题讨论】:
https://github.com/google/codesearch/blob/master/index/write.go#L581
我看上面是为了测试两个字节是否可以出现在一个有效的 UTF8 字符串中。但我不明白它是如何工作的。谁能帮我理解为什么这个功能有效?谢谢。
【问题讨论】:
有关编码的说明,请参阅wikipedia。编码为:
num
bytes 1st byte 2nd byte 3rd byte 4 byte
1 0xxxxxxx
2 110xxxxx 10xxxxxx
3 1110xxxx 10xxxxxx 10xxxxxx
4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
为了帮助使代码更容易与维基百科文章进行比较,这里的代码将 < n 重写为 <= n-1 并将整数文字重写为二进制整数文字。
func validUTF8(c1, c2 uint32) bool {
switch {
case c1 <= 0b01111111:
// 1-byte, must be followed by 1-byte or first of multi-byte
return c2 <= 0b01111111 || 0b11000000 <= c2 && c2 <= 0b11110111
case c1 <= 0b10111111:
// continuation byte, can be followed by nearly anything
return c2 <= 0b11110111
case c1 <= 0b11110111:
// first of multi-byte, must be followed by continuation byte
return 0b10000000 <= c2 && c2 <= 0b10111111
}
return false
}
第一种情况检查 1 字节编码 (0xxxxxxx) 之后的字节。
第二种情况检查后续字节(10xxxxxx)之后的字节。
第三种情况检查多字节编码(110xxxx、1110xxxx、11110xxx)开始之后的字节。
该函数报告两个字节是否可以采用有效的 UTF-8 编码。有效字节对序列不一定是有效的 UTF-8 编码。
【讨论】:
使用标准库的unicode/utf8 模块可能比使用该函数更适合您的任务。查看utf8.Valid 文档。
【讨论】:
utf8.Valid,每两个字节调用一次。更好的解决方案(性能方面)可能正在处理您的字符串块(考虑边缘情况)。无论如何考虑利用utf8.Valid或其source code。
Valid()函数保留的部分是否仍然有效?