2016年12月12日 星期一

位元組順序

因為不同電腦,資料儲存的位元組順序可能不同,所以電腦間要用網路傳輸資料時,要注意位元組的順序,才不會傳輸後,因解讀順序不同,導致資料意義變了。

一個整數資料,依將高數位資料,放在儲存位址的前或後,可區分為 big-endian、little-endian 兩種儲存順序,而在網路傳輸 TCP/IP 協議是使用 big-endian。
  • big-endian(大端序、大尾序):
    多位的整數,高位數存放在儲存位址前面(高位數放在前面的低位址,低位數放在後面的高位址)
  • little-endian(小端序、小尾序):
    多位的整數,低位數(Least Significant Bit、LSB)存放在儲存位址前面(低位數放在前面的低位址,高位數放在後面的高位址)
  • network byte order(網絡位元組序、網絡序):一般為大端序。
例如:一個16進位 int ,0x12345678,
高位數~低位數依序為:12、34、56、78
共占儲存位址4個位元組:0x100~0x103
大端序在每個位元組存放的資料 0x100:12、0x101:34、0x102:56、0x103:78
小端序在每個位元組存放的資料 0x100:78、0x101:56、0x102:34、0x103:12


相關名詞:
  • 最高有效位(Most Significant Bit,msb):
    n位二進位數字中的n-1位。有符號二進位數,負數採用反碼或補碼形式,此時msb用來表示符號,msb為1表示負數,0表示正數。
  • MSB(Most Significant Byte):
    多字節序列中具有最大權重的字節。
  • 最低有效位(Least Significant Bit,lsb):
    一個二進位數字中的第0位(即最低位)。二進位數中的最小的單位,可以用來指示數字很小的變化。
  • LSB(Least Significant Byte):
    多字節序列中最小權重的字節。

使用 PHP 判斷系統是大端序或小端序
//方法1
function isBigEndian() {
    $bin = pack("L", 0x12345678);
    $hex = bin2hex($bin);
    if (ord(pack("H2", $hex)) === 0x78) {
        return FALSE;
    }

    return TRUE;
}
//方法2
function isLittleEndian() {
    $testint = 0x00FF;
    $p = pack('S', $testint);
    return $testint===current(unpack('v', $p));
}
//方法3
function isLittleEndian() {
    return unpack('S',"\x01\x00")[1] === 1;
}


參考:
位元組順序 - 維基百科,自由的百科全書
PHP: 深入pack/unpack - 陈亦的个人页面 - 开源中国社区
How to get the endianness type in PHP?


其他:C-style strings 在記憶體體中位置。
截錄 Big and Little Endian
「Here are some facts you should know about C-style strings and arrays.
1.C-style strings are stored in arrays of characters.
2.Each character requires one byte of memory, since characters are represented in ASCII (in the future, this could change, as Unicode becomes more popular).
3.In an array, the address of consecutive array elements increases. Thus, & arr[ i ] is less than & arr[ i + 1 ].
4.What's not as obvious is that if something is stored in increasing addresses in memory, it's going to be stored in increasing "addresses" in a file. When you write to a file, you usually specify an address in memory, and the number of bytes you wish to write to the file starting at that address.

So, let's imagine some C-style string in memory. You have the word "cat". Let's pretend 'c' is stored at address 1000. Then 'a' is stored at 1001. 't' is at 1002. The null character '\0' is at 1003.
Since C-style strings are arrays of characters, they follow the rules of characters.」



沒有留言:

張貼留言