字节序:Big Endian 和 Little Endian
最近碰到了node.js中的buf.readUInt16LE(offset[, noAssert])方法:
? ? ? ? 根據指定的偏移量,使用特殊的 endian 字節序格式讀取一個無符號 16 位整數。若參數 noAssert 為 true 將不會驗證 offset 偏移量參數。 這意味著 offset 可能會超出 buffer 的末尾。默認是 false。
? ? ? ? ? ?搜了下字節序這個概念:
轉自:https://blog.csdn.net/lisonglisonglisong/article/details/45421091
?
一、字節序
字節序,也就是字節的順序,指的是多字節的數據在內存中的存放順序。
在幾乎所有的機器上,多字節對象都被存儲為連續的字節序列。例如:如果C/C++中的一個int型變量 a 的起始地址是&a = 0x100,那么 a 的四個字節將被存儲在存儲器的0x100, 0x101, 0x102, 0x103位置。
根據整數 a 在連續的 4 byte 內存中的存儲順序,字節序被分為大端序(Big Endian) 與 小端序(Little Endian)兩類。 然后就牽涉出兩大CPU派系:
Motorola 6800,PowerPC 970,SPARC(除V9外)等處理器采用 Big Endian方式存儲數據;
x86系列,VAX,PDP-11等處理器采用Little Endian方式存儲數據。
另外,還有一些處理器像ARM, DEC Alpha的字節序是可配置的。
?
二、大端與小端
那么,到底什么是大端,什么是小端? 如下圖:
? ? ? ? ? ? ? ?
?
我相信上面的圖已經夠直觀了。也就是說:
Big Endian 是指低地址端 存放 高位字節。
Little Endian 是指低地址端 存放 低位字節。
各自的優勢:
Big Endian:符號位的判定固定為第一個字節,容易判斷正負。
Little Endian:長度為1,2,4字節的數,排列方式都是一樣的,數據類型轉換非常方便。
三、為什么要注意字節序
如果你寫的程序只在單機環境下面運行,并且不和別人的程序打交道,那么你完全可以忽略字節序的存在。
但是,如果你的程序要跟別人的程序產生交互呢? 比如,當一個 C/C++ 的程序要與一個 Java 程序交互時:
C/C++語言編寫的程序里數據存儲順序是跟編譯平臺所在的CPU相關的,而現在比較普遍的 x86 處理器是 Little Endian
JAVA編寫的程序則唯一采用 Big Endian 方式來存儲數據
試想,如果你的C/C++程序將變量 a = 0x12345678 的首地址傳遞給了Java程序,由于Java采取 Big Endian 方式存儲數據,很自然的它會將你的數據翻譯為 0x78563412。顯然,問題就出現了!!!
另外,網絡傳輸一般采用 Big Endian,也被稱之為網絡字節序,或網絡序。當兩臺采用不同字節序的主機通信時,在發送數據之前都必須經過字節序的轉換成為網絡字節序后再進行傳輸。
四、判斷機器的字節序
由于 C/C++ 存儲數據時的字節序依賴所在平臺的CPU,所以我們可以通過C/C++程序判定機器的端序:
五、網絡序和主機序
網絡字節序:TCP/IP各層協議將字節序定義為 Big Endian,因此TCP/IP協議中使用的字節序是大端序。
主機字節序:整數在內存中存儲的順序,現在 Little Endian 比較普遍。(不同的 CPU 有不同的字節序)
在進行網絡通信時 通常需要調用相應的函數進行主機序和網絡序的轉換。Berkeley socket API 定義了一組轉換函數,用于16和32bit整數在網絡序和本機字節序之間的轉換。htonl,htons用于本機序轉換到網絡序;ntohl,ntohs用于網絡序轉換到本機序。
---------------------?
?
總結
以上是生活随笔為你收集整理的字节序:Big Endian 和 Little Endian的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jacob使用入门
- 下一篇: 读《史蒂夫•乔布斯传》(一)