iOS 網路程式設計大小端格式
一、概念:
不同的CPU有不同的位元組序型別,指在記憶體中的儲存順序。
常見的有兩種:
1.Little-endian: 將低序位元組儲存在起始地址(低位編碼,低位開始);
2.Big-endian: 將高序位元組儲存在起始位置(高位編碼,高位開始);
LE(little-endian):
符合人的思維的位元組序
地址低位儲存值的低位
地址高位儲存值的高位
BE(big-endian):
直觀的位元組序
地址低位儲存值的高位
地址高位儲存值得低位
二、例子:
0x01020304 (DWORD)在記憶體地址4000 4001 4002 4003的儲存方式:
記憶體地址:4000400140024003
LE:0403 0201
BE:0102 0304
注:每個地址存1個位元組,每個字有4個位元組。2位16進位制數是1個位元組(0xFF = 1111 1111)
三、注意:
1.x86系列的CPU都是little-endian的位元組序;
2.一般作業系統都是小端,而通訊協議是大端的;
3.建立CPU的位元組序:
Big-Endian: PowerPC、IBM、Sun
Little-Endian:x86、DEC
ARM既可以工作在大端模式,也可以工作在小端模式。
4.常見的檔案的位元組序:
Adobe PS : Big Endian
BMP: Little Endian
DXF(AutoCAD):Variable
GIF:Little Endian
JPEG:Little Endian
MacPaint: Big Endian
RTF:Little Endian
四、工具:
1.判斷機器的位元組序:
BOOL isBigEndian()
{
int a = 0x1234;
// 通過將int強制型別轉換成char單位元組,通過判斷其實儲存位置
char b = *(char *)&a;
if (b == 0x12) {
return YES;
}
return NO;
}
2.聯合體 union的存放順序死所有的成員都從地地址開始存放,利用該特性就可以輕鬆獲得CPU對記憶體採用的Little-endian還是Big-endian模式讀寫:
BOO isBigEndian()
{
union NUM
{
int a;
char b;
} num;
num.a = 0x1234;
if (num.b == 0x12) {
return YES;
}
return NO;
}
/**
* @brief 64位資料高度和低地址的交換
*
* @param A 值
*
* @return 返回結果
*/
#define BigSwapLittle64(A) ((((uint64)(A) & 0xff00000000000000) >> 56) | \
(((uint64)(A) & 0x00ff000000000000) >> 40) | \
(((uint64)(A) & 0x0000ff0000000000) >> 24) | \
(((uint64)(A) & 0x000000ff00000000) >> 8) | \
(((uint64)(A) & 0x00000000ff000000) << 8) | \
(((uint64)(A) & 0x0000000000ff0000) << 24) | \
(((uint64)(A) & 0x000000000000ff00) << 40) | \
(((uint64)(A) & 0x00000000000000ff) << 56))
/**
* @brief 32位資料高度和低地址的交換
*
* @param A 值
*
* @return 返回結果
*/
#define BigSwapLittle32(A) ((((uint32)(A) & 0xff000000) >> 24) | \
(((uint32)(A) & 0x00ff0000) >> 8) | \
(((uint32)(A) & 0x0000ff00) << 8) | \
(((uint32)(A) & 0x000000ff) << 24))
/**
* @brief 16位資料高度和低地址的交換
*
* @param A 值
*
* @return 返回結果
*/
#define BigSwapLittle16(A) ((((uint16)(A) & 0xff00) >> 8) | \
(((uint16)(A) & 0x00ff) << 8))
五、備註參考:
六、資料下載:
1.iOS 網路程式設計,client 與 server 大小端格式問題,Objective-C語言工具一份:自定義的父類