久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

大端和小端

 郭恩 2018-06-10

  在計算機中是以字節(jié)為單位,,每個地址對應一個字節(jié),,一個字節(jié)8bit。在C中,,除了8bit的char以外,,還有16bit的short,32位的int,,64位long,,當然具體要由編譯器決定,可以通過sizeof來獲取不同類型在內(nèi)存中占用的字節(jié)數(shù),。在計算機系統(tǒng)中,,當物理單位的長度大于1個字節(jié)時,就要區(qū)分字節(jié)順序,。常見的字節(jié)順序有兩種:Big Endian(High-byte first)和Litter Endian(Low-byte first),,當然還有其他字節(jié)順序,但不常見,,例如Middle Endian,。

一,、最高有效位、最低有效位

  要理解Big Endian和Little Endian,,首先要搞清楚MSB和LSB,。

  1、MSB(Most Significant Bit)最高有效位

    在一個n位二進制數(shù)字中n-1位,,也就是最左邊的位,。

  2、LSB(Least Significant Bit)最低有效位

    指最右邊的位,。

  例如:一個int類型的整型123456789

    二進制表達方式:0000 0111 0101 1011 1100 1101 0001 0101(從右向左,,每4bit對齊,最左邊(高位)不夠用0補齊)

    十六進制表達方式:0 7 5 B C D 1 5

    按照上述關(guān)于MSB和LSB的意思,,在二進制表達方式中,,bit從0開始,從右向左,,bit0為最低有效位,,而bit23為最高有效位。而我們一般稱左邊的0x07為高位字節(jié),,0x15為低位字節(jié),。

    再通俗一點解釋就是:8421碼的,8這端為高位,,1這端為低位,,相應的字節(jié)則分別稱為高位字節(jié)和低位字節(jié)。

二,、內(nèi)存地址

  在內(nèi)存中,,多字節(jié)對象都是被存儲為連續(xù)的字節(jié)序列。例如在C語言中,,一個類型為int的變量n,,如果其存儲的首個字節(jié)的地址為0x1000,那么剩余3個字節(jié)的地址將存儲在0x1001~0x1003,??傊还芫唧w字節(jié)順序是以什么方式排列,,內(nèi)存地址的分配一般是從小到大的增長,。我們常把0x1000稱為低地址端,把0x1003稱為高地址端,。

三,、大端和小端

  搞清楚MSB、LSB,、高位字節(jié),、低位字節(jié),、內(nèi)存地址之后,再理解大端和小端,,就相當容易了,,先看看概念:

    小端Little Endian:低字節(jié)存放在低地址,低位字節(jié)排放在內(nèi)存的低地址端,,高位字節(jié)排放在內(nèi)存的高地址端,。

    大端Big Endian:高字節(jié)存放在低地址,即高位字節(jié)排放在內(nèi)存的低地址端,,低位字節(jié)排放在內(nèi)存的高地址端,。

  以二節(jié)中的例子int類型整數(shù)123456789為例:

    小端在內(nèi)存中排列:0x15 0xCD 0x5B 0x07 (低位在前)

    大端在內(nèi)存中排列:0x07 0x5B 0xCD 0x15 (高位在前)

  從例子中可以看出小端比較符合人的思維,而大端則看上去非常直觀,。

  注:

    1,、例子中是假設(shè)編譯器支持int為32位的前提下,如果是16位,,那大端的排列則為:0xCD 0x15 0x07 0x5B,。

    2、大小端一般是由CPU架構(gòu)決定,,常見的Intel,、AMD的CPU使用的是小端字節(jié)序,而PowerPC使用的是大端字節(jié)序,,有些ARM處理器還可以選擇用大端還是小端模式,,具體請自行查閱。

    3,、c#中,,字節(jié)序跟編譯平臺所在的CPU相關(guān),例如在Intel x86 CPU架構(gòu)的windows平臺中,,c#采用的小端序。而Java由于其JVM屏蔽了不同CPU架構(gòu)導致的字節(jié)序差異,,所以默認采用大端字節(jié)序,。所以,大小端模式是由CPU決定,,而編譯器又可能會改變這種模式,。

字節(jié)序 內(nèi)存地址 int(16bit) int(32bit) 特點
小端 0x1001,0x1002,0x1003,0x1004 0x15 0xCD 0x5B 0x07 0x15 0xCD 0x5B 0x07 低地址端存儲低位字節(jié),低位在前
大端 0x1001,0x1002,0x1003,0x1004 0xCD 0x15 0x07 0x5B 0x07 0x5B 0xCD 0x15 低地址端存儲高位字節(jié),,高位在前

四,、網(wǎng)絡(luò)字節(jié)序和主機字節(jié)序

  網(wǎng)絡(luò)字節(jié)序(Network Order):TCP/IP各層協(xié)議將字節(jié)序定義為Big Endian,因此TCP/IP協(xié)議中使用的字節(jié)序通常稱之為網(wǎng)絡(luò)字節(jié)序,。

  主機字節(jié)序(Host Order):整數(shù)在內(nèi)存中保存的順序,,它遵循Little Endian規(guī)則(不一定,,要看主機的CPU架構(gòu))。所以當兩臺主機之間要通過TCP/IP協(xié)議進行通信的時候就需要調(diào)用相應的函數(shù)進行主機序列(Little Endian)和網(wǎng)絡(luò)序(Big Endian)的轉(zhuǎn)換,。

  如果是做跨平臺開發(fā)時,,雙方需要協(xié)商好字節(jié)序,然后根據(jù)程序運行的環(huán)境,,確定是否需要字節(jié)序轉(zhuǎn)換,。

例如約定的通訊字節(jié)序位Big Endian,默認的windows采用的Little Endian,,那收到數(shù)據(jù)后就需要做轉(zhuǎn)換操作,。

五、C#位操作符

  這里簡單記錄一下C#的位操作符,,方便以后自己查閱,,也方便理解后面的講解。

  1,、按位與&

    1&0為0,;0&0為0;1&1為1,。

  2,、按位或|

    1|0為1;0|0為0,;1|1為1,。

  3、按位取反~

    ~1為0,;~0為1,。

  4、按位異或^

    1^1為0,;0^0為0,;1^0為1。相等得0,,相異等1,。

  5、左移<<

    位左移運算,,將整個數(shù)向左移若干位,,左移后空出的部分用0補齊。

  6,、右移>>

    位右移運算,,將整個數(shù)向右移若干位,右移后空出的部分用0補齊。

六,、C#中關(guān)于大端和小端的轉(zhuǎn)換
  1,、重復輪子

using System;

namespace Framework.NetPackage.Common
{
    /// <summary>
    /// 字節(jié)序轉(zhuǎn)換輔助類
    /// </summary>
    public static class Endian
    {
        public static short SwapInt16(this short n)
        {
            return (short)(((n & 0xff) << 8) | ((n >> 8) & 0xff));
        }

        public static ushort SwapUInt16(this ushort n)
        {
            return (ushort)(((n & 0xff) << 8) | ((n >> 8) & 0xff));
        }

        public static int SwapInt32(this int n)
        {
            return (int)(((SwapInt16((short)n) & 0xffff) << 0x10) |
                          (SwapInt16((short)(n >> 0x10)) & 0xffff));
        }

        public static uint SwapUInt32(this uint n)
        {
            return (uint)(((SwapUInt16((ushort)n) & 0xffff) << 0x10) |
                           (SwapUInt16((ushort)(n >> 0x10)) & 0xffff));
        }

        public static long SwapInt64(this long n)
        {
            return (long)(((SwapInt32((int)n) & 0xffffffffL) << 0x20) |
                           (SwapInt32((int)(n >> 0x20)) & 0xffffffffL));
        }

        public static ulong SwapUInt64(this ulong n)
        {
            return (ulong)(((SwapUInt32((uint)n) & 0xffffffffL) << 0x20) |
                            (SwapUInt32((uint)(n >> 0x20)) & 0xffffffffL));
        }
    }
}

  2、BCL庫支持的函數(shù)

    System.Net.IPAddress.HostToNetworkOrder,、System.Net.IPAddress.NetworkToHostOrder,,這兩個函數(shù)的內(nèi)部實現(xiàn)和上面重復輪子原理一模一樣。

七,、關(guān)于負數(shù)

  在計算機中,,負數(shù)以其絕對值的補碼形式表示,不明白可以查閱九中貼出的相關(guān)資源,。關(guān)于負數(shù)的字節(jié)序跟一般整數(shù)的字節(jié)序處理沒有任何區(qū)別,。

八、關(guān)于漢字編碼以及與字節(jié)序的關(guān)系

  1,、對于gb2312,、gbk、gb18030,、big5,,其編碼某個漢字產(chǎn)生的字節(jié)順序,由其編碼方案本身決定,,不受CPU字節(jié)序的影響,。其實這幾種編碼的字節(jié)序和大端模式的順序是一致的。

  在使用GB2312的程序通常采用EUC儲存方法,,以便兼容于ASCII,。瀏覽器編碼表上的“GB2312”,通常都是指“EUC-CN”表示法,。
每個漢字及符號以兩個字節(jié)來表示,。第一個字節(jié)稱為“高位字節(jié)”,第二個字節(jié)稱為“低位字節(jié)”,。
  “高位字節(jié)”使用了0xA1-0xF7(把01-87區(qū)的區(qū)號加上0xA0),,“低位字節(jié)”使用了0xA1-0xFE(把01-94加上0xA0)。

  由于一級漢字從16區(qū)起始,,漢字區(qū)的“高位字節(jié)”的范圍是0xB0-0xF7,,“低位字節(jié)”的范圍是0xA1-0xFE,占用的碼位是72*94=6768,。其中有5個空位是D7FA-D7FE。
  例如“啊”字在大多數(shù)程序中,,會以兩個字節(jié),,0xB0(第一個字節(jié))0xA1(第二個字節(jié))儲存。(與區(qū)位碼對比:0xB0=0xA0+16,0xA1=0xA0+1)。

  2,、UTF-8

      UTF-8和gb系列編碼一樣,,其編碼某個漢字產(chǎn)生的字節(jié)順序,由其編碼方案決定,,不受CPU字節(jié)序的影響,。無論一個漢字有多少個字節(jié),它的字節(jié)序與編碼順序保持一致,。

例如漢字”嚴”利用utf8編碼過程:

1,、已知“嚴”的unicode編碼是4E25(100111000100101),根據(jù)utf8規(guī)則可以得知其utf8編碼需要三個字節(jié),。

  即格式是“1110xxxx 10xxxxxx 10xxxxxx”

  第一個字節(jié)前三位表示了字符“嚴”被編碼成utf8后的編碼長度,,有多長,則從左開始填多少個1,,如果只有1個字節(jié),,則第一個位為0。

  對于編碼后大于1個字節(jié)的符號,,第一個字節(jié)的第四位為0,,其他字節(jié)前兩位均要求為10。

2,、從”嚴“的最后一個二進制位開始,,依次從后向前填入格式中的x,多出的位補0,。這樣就得到了“嚴”的utf8編碼為“11100100 10111000 10100101”,,轉(zhuǎn)換成十六進制就是E4B8A5。

編碼示例過程參考的原文:http://www./blog/2007/10/ascii_unicode_and_utf-8.html

從上述過程可以看到,,utf8的字節(jié)序已經(jīng)由其編碼方案決定,,不受CPU字節(jié)序影響。

  3,、Unicode

    Unicode只是一個符號集,,它只規(guī)定了符號的二進制代碼,卻沒有規(guī)定這個二進制代碼應該如何存儲,。所以他沒有要求如何存儲編碼后的字節(jié),,也就受CPU字節(jié)序的影響。

    Unicode的具體實現(xiàn)包括UTF-16,、UTF-32(當然也包括UTF-8,,但由于其編碼方式和編碼后的字節(jié)序與其他Unicode編碼實現(xiàn)有較大區(qū)別,所以單獨拿出來講解的),。

  4,、總結(jié)

    1,、網(wǎng)絡(luò)通訊

      在實際的網(wǎng)絡(luò)通訊中,網(wǎng)絡(luò)協(xié)議例如TCP是規(guī)定網(wǎng)絡(luò)字節(jié)序(Network Order)是大端,。而針對漢字具體使用什么編碼,,通訊雙方要么提前約定好,要么就需要在數(shù)據(jù)包中標識好漢字具體使用的編碼,。

      如果在網(wǎng)絡(luò)通訊中,,涉及例如UTF16這樣區(qū)分大小端的編碼,,除非按網(wǎng)絡(luò)協(xié)議要求采用大端模式是,,否則也要事先約定好,或者在數(shù)據(jù)包中標識好使用的字節(jié)序模式,。

    2,、文件

      文件的也會存儲漢字,,當然也要進行編碼。如果采用UTF-16這樣的有字節(jié)序模式區(qū)分的編碼,,編碼規(guī)則要求可以在文件頭部的BOM(Byte Order Mark)來標記,。如果沒有標記,除非事先知道字節(jié)序的模式,,否則只能大小端都試一遍,。

 

  Unicode規(guī)范中推薦的標記字節(jié)順序的方法是BOM。BOM不是“Bill Of Material”的BOM表,,而是Byte Order Mark,。BOM是一個有點小聰明的想法:

  在Unicode編碼中有一個叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的編碼是FEFF,。而FEFF在Unicode中是不存在的字符,,所以不應該出現(xiàn)在實際傳輸中。UCS(Unicode的學名)規(guī)范建議我們在傳輸字節(jié)流前,,先傳輸字符“ZERO WIDTH NO-BREAK SPACE”,。

  這樣如果接收者收到FEFF,就表明這個字節(jié)流是Big-Endian的,;如果收到FFFE,,就表明這個字節(jié)流是Little-Endian的。因此字符“ZERO WIDTH NO-BREAK SPACE”又被稱作BOM,。

  UTF-8不需要BOM來表明字節(jié)順序,,但可以用BOM來表明編碼方式。字符“ZERO WIDTH NO-BREAK SPACE”的UTF-8編碼是EF BB BF,。所以如果接收者收到以EF BB BF開頭的字節(jié)流,,就知道這是UTF-8編碼了。

九,、參考資源

  http://baike.baidu.com/view/1922338.htm

  http://www./izualzhy/archive/2011/10/20/158784.html

  http://www.cnblogs.com/junsky/archive/2009/08/06/1540727.html(負數(shù)的二進制表示方法)

  http://www.cnblogs.com/augellis/archive/2009/09/29/1576501.html (sizeof)

  http://www./blog/2007/10/ascii_unicode_and_utf-8.html(漢字編碼)

  http://djt.qq.com/article/view/658?ADTAG=email.InnerAD.weekly.20130902(漢字編碼)

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多