为什么在以下应用程序中将一个字节转换为符号65533而不是132的符文?
我有ascii代码转换表(旧的ascii代码 - >新的ascii代码),我应该实现,所以我需要正确的 ascii 值(在这种情况下为132)转换器。
示例程序:
package main
import (
"io/ioutil"
"flag"
"bytes"
"fmt"
)
func converter(r rune) rune {
fmt.Printf("%v ", int(r))
return r
}
func main() {
// parse the command line
var infile string
flag.StringVar(&infile, "in", "", "input file")
flag.Parse()
// read the whole file at once
b, err := ioutil.ReadFile(infile)
if err != nil {
panic(err)
}
fmt.Printf("%v\n", b)
// convert charset
converted := bytes.Map(converter, b)
fmt.Printf("\n%v\n", converted)
}
示例输入文件(十六进制):
4A 84 6C 6B 0D 0A
应用程序的示例输出:
[74 132 108 107 13 10]
74 65533 108 107 13 10
[74 239 191 189 108 107 13 10]
答案 0 :(得分:1)
符文是Unicode值,而不是ASCII。所以你的字节被解释为UTF8。
如果我们查看您正在使用的功能: https://golang.org/src/bytes/bytes.go?s=9029:9081#L344
我们可以看到,对于切片中的每个字节,它都会转换为Unicode符文。
r := rune(s[i])
它的作用是从s [i]开始到UTF8字母的字节转换。
在UTF8中,一个字母即可 占用多一个字节。这与ASCII编码相反 一个字母总是需要一个字节。
您可以在此处了解有关UTF8的更多信息https://en.wikipedia.org/wiki/UTF-8
这就是你得错的原因。
要修复它,您应该使用范围循环迭代字节并将输出保存到新切片。
func converter(b byte) byte {
fmt.Printf("%v ", int(r))
return b
}
...
converted := make([]byte, len(b))
for i, v := range b {
// v is your byte value - convert it here
converted[i] = converter(v)
}
答案 1 :(得分:1)
从文本中读取字节,然后您可以在这些行上使用某些内容 - 输出中的最后一列将与ASCII值相比。
package main
import (
"encoding/hex"
"fmt"
"unicode/utf8"
)
func main() {
//s := "Hello, 世界"
//Assuming the following is the hex you have read in from the file..
b, err := hex.DecodeString("48656c6c6f2c20e4b896e7958c")
if err != nil {
fmt.Println(err)
}
fmt.Println(b)
s := string(b)
for i := 0; i < len(s); {
r, size := utf8.DecodeRuneInString(s[i:])
fmt.Printf("%d\t%c\t%d\n", i, r, r)
i += size
}
anotherWay(s)
}
func anotherWay(s string) {
fmt.Println("\nAnother way")
for i, r := range s {
fmt.Printf("%d\t%c\t%d\n", i, r, r)
}
}