2016-04-05 12 views
1

Von https://en.wikipedia.org/wiki/UTF-8#Invalid_code_points habe ich erfahren, dass U + D800 bis U + DFFF ungültig sind. Also im Dezimalsystem ist es 55296 bis 57343.Warum erkennt die utf8.Validstring-Funktion ungültige Unicode-Zeichen nicht?

Und maximale gültige Unicode ist '\ U0010FFFF'. In Dezimalsystem ist es 1114111

Mein Code:

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") 
    } 
} 

Warum ist ValidString Funktion nicht falsch für ungültiges Unicode-Zeichen als Eingabe gegeben Rückkehr? Ich bin sicher, mein Verständnis ist falsch, könnte jemand erklären?

Antwort

3

Ihr Problem tritt in Sprintf. Da Sie ein ungültiges Zeichen eingeben, wird Sprintf durch rune(65533) ersetzt. Dabei wird anstelle von ungültigen Zeichen das Unicode-Ersatzzeichen verwendet. Ihre Zeichenfolge ist also gültig UTF8.

Dies wird auch passieren, wenn Sie so etwas tun: str := string([]rune{ 55297 }) so könnte dies etwas sein, das beim Erstellen von Runen passiert. Es ist nicht sofort ersichtlich, aus: https://blog.golang.org/strings

Wenn Sie Ihre Zeichenfolge erzwingen möchten Sie ungültige UTF8 enthalten können die erste Zeichenfolge wie folgt schreiben:

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

Sie nehmen einen ungültigen Wert und konvertieren ihn mit Sprintf. Es wird in den Fehlerwert konvertiert. Sie überprüfen dann den Fehlerwert, der ein gültiger Unicode-Codepunkt ist.

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") 
    } 

} 

Ausgang:

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 
Verwandte Themen