已复制
全屏展示
复制代码

Golang 之 int string hex []byte 相互转换


· 9 min read

一. 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
}
🔗

文章推荐