標籤:little lib ring out short 情況 dmi show 使用
位元組序是指多位元組資料在電腦記憶體中儲存或者網路傳輸時各位元組的儲存順序。常見的主要有以下2種:
- 小端序(Little-Endian):低位位元組排放在記憶體的低地址端即該值的起始地址,高位位元組排放在記憶體的高地址端。最符合人的思維的位元組序,地址低位儲存值的低位,地址高位儲存值的高位。該序因為從人的第一觀感來說低位值小,就應該放在記憶體位址小的地方,也即記憶體位址低位,反之,高位值就應該放在記憶體位址大的地方,也即記憶體位址高位。在80X86平台上,系統將多位元組中的低位儲存在變數起始地址,使用小端法。
- 大端序(Big-Endian):高位位元組排放在記憶體的低地址端即該值的起始地址,低位位元組排放在記憶體的高地址端。最直觀的位元組序,地址低位儲存值的高位,地址高位儲存值的低位。該序不需考慮對應關係,只需要把記憶體位址從左至右按照由低到高的順序寫出把值按照通常的高位到低位的順序寫出,兩者對照,一個位元組一個位元組的填充進去。
常見的還一種是網路序,即網路位元組順序,它是TCP/IP中規定好的一種資料表示格式,它與具體的CPU類型、作業系統等無關,從而可以保證資料在不同主機之間傳輸時能夠被正確解釋,網路位元組順序採用big endian排序方式。
在C語言中,為了進行轉換,socket庫中提供了轉換函式,包括下面四個:
- htons:把unsigned short類型從主機序轉換到網路序
- htonl:把unsigned long類型從主機序轉換到網路序
- ntohs:把unsigned short類型從網路序轉換到主機序
- ntohl:把unsigned long類型從網路序轉換到主機序
在使用little endian的系統中,這些函數會把位元組序進行轉換;在使用big endian類型的系統中,這些函數會定義成空宏而不作任何轉換。【例】如對於整數0x12345678,在Windows系統上(小端序儲存)使用C語言和Python語言查看其不同表示方式。其位[0-31]表示方式為:小端序(Little-Endian)和大端序(Big-Endian)的表示方式為:其網路位元組序同大端法表示相同。(1)C語言程式:
1 #include <iostream> 2 #include <WinSock.h> 3 #pragma comment(lib, "ws2_32") 4 using namespace std; 5 6 void main() 7 { 8 int a = 0x12345678; 9 cout<<"a = "<<showbase<<hex<<a<<endl;10 cout<<"Little Endian: [";11 for (int i=0; i<4; i++)12 {13 cout<<int(*((char*)&a+i))<<" ";14 }15 cout<<"]"<<endl;16 17 int b = htonl(a);18 cout<<"Big Endian: [";19 for (int i=0; i<4; i++)20 {21 cout<<int(*((char*)&b+i))<<" ";22 }23 cout<<"]"<<endl;24 25 getchar();26 }
其運行結果為:
在調試狀態下,在記憶體視窗中查看變數a和變數b的地址,也可以清晰的看到兩種位元組序的不同儲存情況。本例中變數a和變數b的地址分別為0x00B3FD3C和0x00B3FD24:
(2)Python語言程式:
1 # -*- coding: utf-8 -*-# 2 3 #------------------------------------------------------------------------------- 4 # Name: LittleAndBigEndianTest 5 # Description: 6 # Author: Administrator 7 # Date: 2018/7/8 8 #------------------------------------------------------------------------------- 9 10 import sys11 from struct import *12 from ctypes import *13 import numpy as np14 15 a = 0x1234567816 print(‘a: ‘ + hex(a))17 for name, fmt in zip([‘LittleEndian: ‘, ‘BigEndian: ‘, ‘Network: ‘], [Struct(‘<1i‘), Struct(‘>1i‘), Struct(‘!1i‘)]):18 buffer = create_string_buffer(fmt.size)19 fmt.pack_into(buffer, 0, a)20 data = np.frombuffer(buffer, dtype=np.uint8)21 print(name + str(map(lambda x: hex(x), data)))
其運行結果為:
結果同C語言版本一致,同時也驗證了網路位元組序同大端序結果完全相同。
位元組序的理解----C語言和Python語言