因为涉及到一些大小端的知识,就直接记录一下。

通讯上,大小端的问题倒是很常见的问题了,数据从一个平台到另一个平台,都是需要考虑这个问题的,数据存储不一样,接受到的数据也是反的,和语言没啥关系,和平台(ARM、X86、Power PC等)有关系。

定义

  • Little-Endian:就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
  • Big-Endian:就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

数据:0x12345678存储。

地址 0x001 0x002 0x003 0x004
大端模式 0x12 0x34 0x56 0x78
地址 0x001 0x002 0x003 0x004
小端模式 0x78 0x56 0x34 0x12

区分

C语言:

指针

1
2
3
4
5
6
int i=1;   
char *p=(char *)&i;
if(*p == 1)
printf("小端模式");
else // (*p == 0)
printf("大端模式");

联合体union:

1
2
3
4
5
6
7
8
9
10
11
12
//return 1 : little-endian
// 0 : big-endian
int checkEndian()
{
union {
unsigned int a;
unsigned char b;
} c;

c.a = 1;
return (c.b == 1);
}

Go语言中,因为和C类似,同样可以使用指针的判断方式,来做这个判断操作。

1
2
3
4
5
6
7
8
9
10
//true = big endian, false = little endian
func getEndian() (ret bool) {
var i int = 0x1
bs := (*[4]byte)(unsafe.Pointer(&i))
if bs[0] == 0 {
return true
} else {
return false
}
}

转换大小端

Go语言:

1
2
3
4
5
func BytesReverse(data []byte) {
for i, j := 0, len(data)-1; i < j; i, j = i+1, j-1 {
data[i], data[j] = data[j], data[i]
}
}

颠倒数组,将字节序给逆转过来。可用于结构体数据发送时进行转换,先转成byte数组,然后转换字节序。

这里分享个经验,因为平台不一样,64位平台,int类型所占字节是不同的,这个类型是可以自动变化的(根据平台位数),64位是8字节,若不注意这个点,会造成通信平台字节错位。