Golang 之 int string hex []byte 相互转换
一. int 转 []byte
int分为有符号型(int)和无符号型(uint),从使用的角度说,区别就是能支持的数范围大小。
- 比如 int8 有符号型的范围是 -128 ~ 127
- 比如 uint8无符号型的范围是 0 ~ 255
大端和小端解决的是内存地址和字节数据保存的顺序问题
- 大端存储:大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。内存地址由小向大增加,而数据从高位往低位放,比如4个字节的数组
[0 0 1 0]
表示十进制数 256。通常在计算机网络的TCP/IP协议中使用大端存储表示 - 小端存储:小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。高位内存地址和数据的高位相对应,低位内存地址和数据的低位相对应,比如4个字节的数组
[0 1 0 0]
表示十进制数 256
- 下面是有符号型和无符号型的数字转为指定字节数的方法,源码见附录部分。
func main() {
var b []byte
var e error
b, e = IntToBytes(128, 1, binary.BigEndian)
fmt.Println(b, e)
b, e = UintToBytes(65535, 8, binary.BigEndian)
fmt.Println(b, e)
}
// 输出结果
[] The number(128) is greater than 127 or less than -128 for bytes of 1
[0 0 0 0 0 0 255 255] <nil>
二. string 转 []byte
var s string = "able"
var b []byte = []byte(s)
fmt.Println(s, b)
// 输出结果
able [97 98 108 101]
三. []byte 转 int
[]byte 转 int,可以借助binary.Read读取指定大小字节的数据,并给出是大端存储还是小端存储,最后强制转为int64,如果字节数不满足的话,使用0来补充,下面是示例,源码见附录。
func main() {
b := []byte{128}
i, _ := BytesToInt(b, binary.BigEndian)
fmt.Println(i)
c := []byte{255}
j, _ := BytesToUint(c, binary.BigEndian)
fmt.Println(j)
}
// 输出结果为
-128
255
四. []byte 转 string
直接使用string强制转换
var b = []byte("你是我的xxx")
fmt.Println(string(b))
// 输出结果
你是我的xxx
五. []byte 转 hex string
字节数组转换成十六进制形式的字符串。
var b = []byte("abc xyz")
var s = hex.EncodeToString(b)
fmt.Println(s)
// 输出结果
6162632078797a
六. hex string 转 []byte
s := "6162632078797a"
b, err := hex.DecodeString(s)
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(b)
// 输出结果
[97 98 99 32 120 121 122]
七. 附录
7.1 int 转 []byte 源码
package main
import (
"bytes"
"encoding/binary"
"fmt"
)
func main() {
var b []byte
var e error
b, e = IntToBytes(128, 1, binary.BigEndian)
fmt.Println(b, e)
b, e = UintToBytes(65535, 8, binary.BigEndian)
fmt.Println(b, e)
}
func IntToBytes(number int64, byteSize int, byteOrder binary.ByteOrder) ([]byte, error) {
var err error
var min int64
var max int64
var bytesArray []byte
var bytesBuffer = new(bytes.Buffer)
switch byteSize {
case 1:
min = -128 // - power(2, 7)
max = 127 // power(2, 7) - 1
if number < min || number > max {
err = fmt.Errorf("The number(%d) is greater than %d or less than %d for bytes of %d ", number, max, min, byteSize)
break
}
i := int8(number)
err = binary.Write(bytesBuffer, binary.BigEndian, i)
bytesArray = bytesBuffer.Bytes()
case 2:
min = -32768 // - power(2, 15)
max = 32767 // power(2, 15) - 1
if number < min || number > max {
err = fmt.Errorf("The number(%d) is greater than %d or less than %d for bytes of %d ", number, max, min, byteSize)
break
}
i := int16(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
}
bytesArray = bytesBuffer.Bytes()
case 3:
min = -8388608 // - power(2, 23)
max = 8388607 // power(2, 23) - 1
if number < min || number > max {
err = fmt.Errorf("The number(%d) is greater than %d or less than %d for bytes of %d ", number, max, min, byteSize)
break
}
i := int32(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
bytesArray = bytesBuffer.Bytes()[1:]
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
bytesArray = bytesBuffer.Bytes()[:3]
}
case 4:
min = -2147483648 // - power(2, 31)
max = 2147483647 // power(2, 31) - 1
if number < min || number > max {
err = fmt.Errorf("The number(%d) is greater than %d or less than %d for bytes of %d ", number, max, min, byteSize)
break
}
i := int32(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
}
bytesArray = bytesBuffer.Bytes()
case 5:
min = -549755813888 // - power(2, 39)
max = 549755813887 // power(2, 39) - 1
if number < min || number > max {
err = fmt.Errorf("The number(%d) is greater than %d or less than %d for bytes of %d ", number, max, min, byteSize)
break
}
i := int64(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
bytesArray = bytesBuffer.Bytes()[3:]
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
bytesArray = bytesBuffer.Bytes()[:5]
}
case 6:
min = -140737488355328 // - power(2, 47)
max = 140737488355327 // power(2, 47) - 1
if number < min || number > max {
err = fmt.Errorf("The number(%d) is greater than %d or less than %d for bytes of %d ", number, max, min, byteSize)
break
}
i := int64(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
bytesArray = bytesBuffer.Bytes()[2:]
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
bytesArray = bytesBuffer.Bytes()[:6]
}
case 7:
min = -36028797018963968 // - power(2, 55)
max = 36028797018963967 // power(2, 55) - 1
if number < min || number > max {
err = fmt.Errorf("The number(%d) is greater than %d or less than %d for bytes of %d ", number, max, min, byteSize)
break
}
i := int64(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
bytesArray = bytesBuffer.Bytes()[1:]
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
bytesArray = bytesBuffer.Bytes()[:7]
}
case 8:
min = -9223372036854775808 // - power(2, 63)
max = 9223372036854775807 // power(2, 63) - 1
if number < min || number > max {
err = fmt.Errorf("The number(%d) is greater than %d or less than %d for bytes of %d ", number, max, min, byteSize)
break
}
i := int64(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
}
bytesArray = bytesBuffer.Bytes()
default:
err = fmt.Errorf("value of byteSize must be one of these: 1 2 3 4 5 6 7 8")
}
if err != nil {
return nil, err
}
return bytesArray, nil
}
func UintToBytes(number uint64, byteSize int, byteOrder binary.ByteOrder) ([]byte, error) {
if number < 0 {
return nil, fmt.Errorf("The number(%d) is less than 0 ", number)
}
var err error
var max uint64
var bytesArray []byte
var bytesBuffer = new(bytes.Buffer)
switch byteSize {
case 1:
max = 255 // power(2, 8) - 1
if number > max {
err = fmt.Errorf("The number(%d) is greater than %d for bytes of %d ", number, max, byteSize)
break
}
i := uint8(number)
err = binary.Write(bytesBuffer, binary.BigEndian, i)
bytesArray = bytesBuffer.Bytes()
case 2:
max = 65535 // power(2, 16) - 1
if number > max {
err = fmt.Errorf("The number(%d) is greater than %d for bytes of %d ", number, max, byteSize)
break
}
i := uint16(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
}
bytesArray = bytesBuffer.Bytes()
case 3:
max = 16777215 // power(2, 24) - 1
if number > max {
err = fmt.Errorf("The number(%d) is greater than %d for bytes of %d ", number, max, byteSize)
break
}
i := uint32(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
bytesArray = bytesBuffer.Bytes()[1:]
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
bytesArray = bytesBuffer.Bytes()[:3]
}
case 4:
max = 4294967295 // power(2, 32) - 1
if number > max {
err = fmt.Errorf("The number(%d) is greater than %d for bytes of %d ", number, max, byteSize)
break
}
i := uint32(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
}
bytesArray = bytesBuffer.Bytes()
case 5:
max = 1099511627775 // power(2, 40) - 1
if number > max {
err = fmt.Errorf("The number(%d) is greater than %d for bytes of %d ", number, max, byteSize)
break
}
i := uint64(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
bytesArray = bytesBuffer.Bytes()[3:]
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
bytesArray = bytesBuffer.Bytes()[:5]
}
case 6:
max = 281474976710655 // power(2, 48) - 1
if number > max {
err = fmt.Errorf("The number(%d) is greater than %d for bytes of %d ", number, max, byteSize)
break
}
i := uint64(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
bytesArray = bytesBuffer.Bytes()[2:]
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
bytesArray = bytesBuffer.Bytes()[:6]
}
case 7:
max = 72057594037927935 // power(2, 56) - 1
if number > max {
err = fmt.Errorf("The number(%d) is greater than %d for bytes of %d ", number, max, byteSize)
}
i := uint64(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
bytesArray = bytesBuffer.Bytes()[1:]
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
bytesArray = bytesBuffer.Bytes()[:7]
}
case 8:
max = 18446744073709551615 // power(2, 64) - 1
if number > max {
err = fmt.Errorf("The number(%d) is greater than %d for bytes of %d ", number, max, byteSize)
break
}
i := uint64(number)
if byteOrder == binary.BigEndian {
err = binary.Write(bytesBuffer, binary.BigEndian, i)
} else {
err = binary.Write(bytesBuffer, binary.LittleEndian, i)
}
bytesArray = bytesBuffer.Bytes()
default:
err = fmt.Errorf("value of byteSize must be one of these: 1 2 3 4 5 6 7 8")
}
if err != nil {
return nil, err
}
return bytesArray, nil
}
7.2 []byte 转 int 源码
package main
import (
"bytes"
"encoding/binary"
"fmt"
)
func main() {
b := []byte{128}
i, _ := BytesToInt(b, binary.BigEndian)
fmt.Println(i)
c := []byte{255}
j, _ := BytesToUint(c, binary.BigEndian)
fmt.Println(j)
}
func BytesToInt(b []byte, order binary.ByteOrder) (int64, error) {
var r int64
var err error
var bytesBuffer = new(bytes.Buffer)
switch len(b) {
case 1:
var i int8
bytesBuffer.Write(b)
if order == binary.BigEndian {
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = int64(i)
case 2:
var i int16
bytesBuffer.Write(b)
if order == binary.BigEndian {
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = int64(i)
case 3:
var i int32
if order == binary.BigEndian {
bytesBuffer.WriteByte(0)
bytesBuffer.Write(b)
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
bytesBuffer.Write(b)
bytesBuffer.WriteByte(0)
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = int64(i)
case 4:
var i int32
bytesBuffer.Write(b)
if order == binary.BigEndian {
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = int64(i)
case 5:
var i int64
if order == binary.BigEndian {
bytesBuffer.Write([]byte{0, 0, 0})
bytesBuffer.Write(b)
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
bytesBuffer.Write(b)
bytesBuffer.Write([]byte{0, 0, 0})
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = int64(i)
case 6:
var i int64
if order == binary.BigEndian {
bytesBuffer.Write([]byte{0, 0})
bytesBuffer.Write(b)
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
bytesBuffer.Write(b)
bytesBuffer.Write([]byte{0, 0})
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = int64(i)
case 7:
var i int64
if order == binary.BigEndian {
bytesBuffer.WriteByte(0)
bytesBuffer.Write(b)
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
bytesBuffer.Write(b)
bytesBuffer.WriteByte(0)
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = int64(i)
case 8:
var i int64
bytesBuffer.Write(b)
if order == binary.BigEndian {
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = int64(i)
default:
err = fmt.Errorf("value of []byte length must be one of these: 1 2 3 4 5 6 7 8")
}
if err != nil {
return 0, err
}
return r, nil
}
func BytesToUint(b []byte, order binary.ByteOrder) (uint64, error) {
var r uint64
var err error
var bytesBuffer = new(bytes.Buffer)
switch len(b) {
case 1:
var i uint8
bytesBuffer.Write(b)
if order == binary.BigEndian {
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = uint64(i)
case 2:
var i uint16
bytesBuffer.Write(b)
if order == binary.BigEndian {
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = uint64(i)
case 3:
var i uint32
if order == binary.BigEndian {
bytesBuffer.WriteByte(0)
bytesBuffer.Write(b)
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
bytesBuffer.Write(b)
bytesBuffer.WriteByte(0)
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = uint64(i)
case 4:
var i uint32
bytesBuffer.Write(b)
if order == binary.BigEndian {
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = uint64(i)
case 5:
var i uint64
if order == binary.BigEndian {
bytesBuffer.Write([]byte{0, 0, 0})
bytesBuffer.Write(b)
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
bytesBuffer.Write(b)
bytesBuffer.Write([]byte{0, 0, 0})
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = uint64(i)
case 6:
var i uint64
if order == binary.BigEndian {
bytesBuffer.Write([]byte{0, 0})
bytesBuffer.Write(b)
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
bytesBuffer.Write(b)
bytesBuffer.Write([]byte{0, 0})
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = uint64(i)
case 7:
var i uint64
if order == binary.BigEndian {
bytesBuffer.WriteByte(0)
bytesBuffer.Write(b)
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
bytesBuffer.Write(b)
bytesBuffer.WriteByte(0)
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = uint64(i)
case 8:
var i uint64
bytesBuffer.Write(b)
if order == binary.BigEndian {
err = binary.Read(bytesBuffer, binary.BigEndian, &i)
} else {
err = binary.Read(bytesBuffer, binary.LittleEndian, &i)
}
r = uint64(i)
default:
err = fmt.Errorf("value of []byte length must be one of these: 1 2 3 4 5 6 7 8")
}
if err != nil {
return 0, err
}
return r, nil
}