編碼原理
Hex編碼就是把一個8位的字節(jié)數(shù)據(jù)用兩個十六進制數(shù)展示出來,編碼時,將8位二進制碼重新分組成兩個4位的字節(jié),其中一個字節(jié)的低4位是原字節(jié)的高四位,另一個字節(jié)的低4位是原數(shù)據(jù)的低4位,高4位都補0,然后輸出這兩個字節(jié)對應十六進制數(shù)字作為編碼。Hex編碼后的長度是源數(shù)據(jù)的2倍
ASCII碼:A (65)
二進制碼:0100_0001
重新分組:0000_0100 0000_0001
十六進制: 4 1
Hex編碼:41
Go使用
Golang 標準庫的使用
func main() {
src := []byte("48656c6c6f20476f7068657221")
//解碼
dst := make([]byte, hex.DecodedLen(len(src)))
n, err := hex.Decode(dst, src)
if err != nil {
log.Fatal(err)
}
fmt.Printf("解碼 %s\n", dst[:n])
//編碼
sdst := make([]byte, hex.EncodedLen(len(dst[:n])))
hex.Encode(sdst, dst[:n])
fmt.Printf("編碼 %s\n", sdst)
}
Go實現(xiàn)
編碼的實現(xiàn)很簡單,高位用右移操作,低位用或操作,高位在前,低位在后
func Encode(dst, src []byte) int {
j := 0
for _, v := range src {
dst[j] = hextable[v>>4]
dst[j+1] = hextable[v&0x0f]
j += 2
}
return len(src) * 2
}
解碼的實現(xiàn)使用了一點小技巧,hextable記錄了16進制的,fromHexChar計算高位和低位的ASCII值,再拼接起來。
const hextable = "0123456789abcdef"
func Decode(dst, src []byte) (int, error) {
i, j := 0, 1
for ; j < len(src); j += 2 {
a, ok := fromHexChar(src[j-1])
if !ok {
return i, InvalidByteError(src[j-1])
}
b, ok := fromHexChar(src[j])
if !ok {
return i, InvalidByteError(src[j])
}
dst[i] = (a << 4) | b
i++
}
if len(src)%2 == 1 {
// Check for invalid char before reporting bad length,
// since the invalid char (if present) is an earlier problem.
if _, ok := fromHexChar(src[j-1]); !ok {
return i, InvalidByteError(src[j-1])
}
return i, ErrLength
}
return i, nil
}
// fromHexChar converts a hex character into its value and a success flag.
func fromHexChar(c byte) (byte, bool) {
switch {
case '0' <= c && c <= '9':
return c - '0', true
case 'a' <= c && c <= 'f':
return c - 'a' + 10, true
case 'A' <= c && c <= 'F':
return c - 'A' + 10, true
}
return 0, false
}