为什么utf8.Validstring函数没有检测到无效的unicode字符?

时间:2016-04-05 12:25:13

标签: unicode go utf-8

https://en.wikipedia.org/wiki/UTF-8#Invalid_code_points开始,我知道U + D800到U + DFFF无效。所以在十进制系统中,它是55296到57343。

最大有效Unicode是' \ U0010FFFF'。在十进制系统中,它是1114111

我的代码:

package main

import "fmt"
import "unicode/utf8"

func main() {

    fmt.Println("Case 1(Invalid Range)")
    str := fmt.Sprintf("%c", rune(55296+1))
    if !utf8.ValidString(str) {
        fmt.Print(str, " is not a valid Unicode")
    } else {
        fmt.Println(str, " is valid unicode character")
    }

    fmt.Println("Case 2(More than maximum valid range)")
    str = fmt.Sprintf("%c", rune(1114111+1))
    if !utf8.ValidString(str) {
        fmt.Print(str, " is not a valid Unicode")
    } else {
        fmt.Println(str, " is valid unicode character")
    }
}

为什么ValidString函数没有为输入的无效unicode字符返回false?我确信我的理解是错的,有人可以解释一下吗?

2 个答案:

答案 0 :(得分:3)

您的问题发生在Sprintf中。因为你给它一个无效字符Sprintf替换为rune(65533),这是使用的unicode替换字符而不是无效字符。所以你的字符串是有效的UTF8。

如果您执行以下操作,也会发生这种情况:str := string([]rune{ 55297 })所以这可能是创建符文时发生的事情。从https://blog.golang.org/strings

开始并不是很明显

如果你想强制你的字符串包含无效的UTF8,你可以像这样编写第一个字符串:

str := string([]byte{237, 159, 193})

答案 1 :(得分:2)

您使用无效值并使用Sprintf进行转换。它被转换为错误值。然后检查错误值,这是一个有效的Unicode代码点。

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {

    fmt.Println("Case 1: Invalid Range")
    str := fmt.Sprintf("%c", rune(55296+1))
    fmt.Printf("%q %X %d %d\n", str, str, []rune(str)[0], utf8.RuneError)
    if !utf8.ValidString(str) {
        fmt.Print(str, " is not a valid Unicode")
    } else {
        fmt.Println(str, " is valid unicode character")
    }

    fmt.Println("Case 2: More than maximum valid range")
    str = fmt.Sprintf("%c", rune(1114111+1))
    fmt.Printf("%q %X %d %d\n", str, str, []rune(str)[0], utf8.RuneError)
    if !utf8.ValidString(str) {
        fmt.Print(str, " is not a valid Unicode")
    } else {
        fmt.Println(str, " is valid unicode character")
    }

}

输出:

Case 1: Invalid Range
"�" EFBFBD 65533 65533
�  is valid unicode character
Case 2: More than maximum valid range
"�" EFBFBD 65533 65533
�  is valid unicode character