邢台网站开发,网站模版网,如何进入设计公司网站,网站开发分几种类型大端和小端传输字节序 大端和小端一、最高有效位、最低有效位1.MSB(Most significant Bit)最高有效位2.LSB(Least Significant Bit)最低有效位 二、内存地址三、大端和小端四、网络字节序和主机字节序五、C#位操作符六、C#中关于大端和小端的转换七、关于负数八、关于汉字编码以… 大端和小端传输字节序 大端和小端一、最高有效位、最低有效位1.MSB(Most significant Bit)最高有效位2.LSB(Least Significant Bit)最低有效位 二、内存地址三、大端和小端四、网络字节序和主机字节序五、C#位操作符六、C#中关于大端和小端的转换七、关于负数八、关于汉字编码以及与字节序的关系网络通讯文件 C#转换代码文件 大端和小端
在计算机中是以字节为单位每一个地址对应一个字节一个字节8bit。在C中除了8bit的char以外还有16bit的short32位的int64位long当然具体要由编译器决定可以通过sizeof来获取不同类型在内存中占用的字节数。在计算机系统中当物理单位的长度大于1个字节时就要区分字节顺序。常见的字节顺序有两种Big Endian(High-byte first) 和 Litter Endian(Low-byte first)当然还有其他字节顺序但不常见例如Middle Endian。
一、最高有效位、最低有效位
要理解Big Endian和Little Endian首先要搞清楚MSB和LSB。
1.MSB(Most significant Bit)最高有效位
在一个n位二进制数字中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 按照上述关于MSB和LSB的意思在二进制表达方式中bit从0开始从右向左bit 0位最低有效位而bit 23为最高有效位。而我们一般称左边的0x07为高位字节0x15为低位字节。 再通俗一点解释就是8421的8这端为高位1这端为低位相应的字节则分别称为高位字节和低位字节。
二、内存地址
在内存中多字节对象都是被存储为连续的字节序列。例如在C语言中一个类型为int的变量n如果其存储的首个字节的地址为0x1000那么剩余3个字节地址将存储在0x1001~0x1003。总之不管具体字节顺序是以什么方式排列内存地址的分配一般是从小到大的增长。 我们常把0x1000称为低地址端把0x1003称为高地址端。
三、大端和小端
搞清楚MSB、LSB、高位字节、低位字节之后再理解大端和小端就相当容易了先看看概念 小端Little Endian低字节存放在低地址低位字节排放在内存的低地址端高位字节排放在内存的高地址端。 大端Big Endian高字节存放在低地址即高位字节排放在内存的低地址端低位字节排放在内存的高地址端。 以二节中的例子int类型整数123456789位例 小端在内存中排列 0x15 0xCD 0x5B 0x07(低位在前) 大端在内存中排列 0x07 0x5B 0xCD 0x15(高位在前) 从例子中可以看出小端比较符合人的思维而大端则看上去非常直观。 注
例子中是假设编译器支持int为32位的前提下如果是16位那大端的排列则为0xCD 0x15 0x07 0x5B大小端一般是由CPU架构决定常见的Intel、AMD的CPU使用的是小端字节而PowerPC使用的是大端字节序有些ARM处理器还可以选择大端还是小端模式具体自行查阅。C#中字节序跟编译平台所在的CPU相关例如在Intel x86 CPU架构的windows平台中C#采用的小端序。而Java由于JVM屏蔽不了不同CPU架构导致额字节序差异所以默认采用大端字节。所以大小端模式是由CPU决定而编译器又可能会改变这种模式。 四、网络字节序和主机字节序
网络字节序(Network Order)TCP/IP各层协议将字节序定义为Big Endian因此TCP/IP协议中的字节序同称之为网络字节序。 主机字节序(Host Order)整数在内存中保存的顺序它遵循Little Endian规则(不一定要看主机的CPU架构)。所以当两台主机之间要通过TCP/IP协议进行通信的时候就需要调用相应的函数进行主机序列(Little Endian)和网络序(Big Endian)的转换。 如果是做跨平台开发时双方需要协商好字节序然后根据程序运行的环境确定是否需要字节序转换。 例如约定的通讯字节序位是Big Endian默认的window采用的Little Endian那收到数据后就需要做转换操作。
五、C#位操作符
这里简单记录一下C#位操作符方便以后自己查阅也方便理解后面的讲解。
按位与 10为000为011为1按位与| 1|0为10|0为01|1为1按位取反~ ~1为0 ~0为1按位异或^ 1^1为0 0^0为0 1^0为1左移 位左移运算将整个数向左移若干位左移后空出的部分0补齐右移 位右移运算将整个数向右移若干位右移后空出的部分用0补齐
六、C#中关于大端和小端的转换
重复轮子
using System;namespace Framework.NetPackage.Common
{/// summary/// 字节序转换辅助类/// /summarypublic 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));}}
}BCL库支持的函数 System.Net.IPaddress.HostToNetworkOrder、System.Net.IPAddress.NetworkToHostOrder这两个函数的内容实现和上面重复轮子原理一样。
/// summary
/// short类型 小端转大端
/// /summary
/// param namenint类型大小/param
/// returns/returns
public static byte[] ShortHostToNetworkOrderBytes(this short n)
{return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(n));
}/// summary
/// short类型 大端转小端
/// /summary
/// param namen/param
/// returns/returns
public static byte[] ShortNetworkToHostOrderBytes(this short n)
{return BitConverter.GetBytes(IPAddress.NetworkToHostOrder(n));
}/// summary
/// short类型 小端转大端
/// /summary
/// param namenint类型大小/param
/// returns/returns
public static short ShortHostToNetworkOrder(this short n)
{return IPAddress.HostToNetworkOrder(n);
}/// summary
/// short类型 大端转小端
/// /summary
/// param namen/param
/// returns/returns
public static short ShortNetworkToHostOrder(this short n)
{return IPAddress.NetworkToHostOrder(n);
}/// summary
/// int类型 小端转大端
/// /summary
/// param namenint类型大小/param
/// returns/returns
public static byte[] IntHostToNetworkOrderBytes(this int n)
{return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(n));
}/// summary
/// int类型 大端转小端
/// /summary
/// param namen/param
/// returns/returns
public static byte[] IntNetworkToHostOrderBytes(this int n)
{return BitConverter.GetBytes(IPAddress.NetworkToHostOrder(n));
}/// summary
/// int类型 小端转大端
/// /summary
/// param namenint类型大小/param
/// returns/returns
public static int IntHostToNetworkOrder(this int n)
{return IPAddress.HostToNetworkOrder(n);
}/// summary
/// int类型 大端转小端
/// /summary
/// param namen/param
/// returns/returns
public static int IntNetworkToHostOrder(this int n)
{return IPAddress.NetworkToHostOrder(n);
}/// summary
/// long类型 小端转大端
/// /summary
/// param namen/param
/// returns/returns
public static byte[] LongHostToNetworkOrderBytes(this long n)
{return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(n));
}/// summary
/// long类型 大端转小端
/// /summary
/// param namen/param
/// returns/returns
public static byte[] LongNetworkToHostOrderBytes(this long n)
{return BitConverter.GetBytes(IPAddress.NetworkToHostOrder(n));
}/// summary
/// long类型 小端转大端
/// /summary
/// param namen/param
/// returns/returns
public static long LongHostToNetworkOrder(this long n)
{return IPAddress.HostToNetworkOrder(n);
}/// summary
/// long类型 大端转小端
/// /summary
/// param namen/param
/// returns/returns
public static long LongNetworkToHostOrder(this long n)
{return IPAddress.NetworkToHostOrder(n);
}七、关于负数
在计算机中负数以及其绝对值的补码形式表示不明白可以查阅九中贴出的相关资源。关于负数的字节序跟一般整数的字节序处理没有任何区别。
八、关于汉字编码以及与字节序的关系
对于gb2312、gbk、gb18030、bigs其编码某个汉字产生的字节顺序由某编码方案本身决定不受CPU字节序的影响。其实这几种编码的字节序和大端模式的顺序是一致的。 UTF-8 UTF-8和gb系列编码一样其编码某个汉字产生的字节顺序由其编码方案决定不受CPU字节序的影响。无论一个汉字有多少个字节它的字节序与编码顺序保持一致。 Unicode
Unicode只是一个符号集它只规定了符号的二进制代码却没有规定这个二进制代码应该如何存储。所以他没有要求如何存储编码后的字节也就受CPU字节序的影响。
Unicode的具体实现包括UTF-16、UTF-32当然也包括UTF-8但由于其编码方式和编码后的字节序与其他Unicode编码实现有较大区别所以单独拿出来讲解的。
总结
网络通讯
在实际的网络通讯中网络协议例如TCP是规定网络字节序Network Order是大端。而针对汉字具体使用什么编码通讯双方要么提前约定好要么就需要在数据包中标识好汉字具体使用的编码。
如果在网络通讯中涉及例如UTF16这样区分大小端的编码除非按网络协议要求采用大端模式是否则也要事先约定好或者在数据包中标识好使用的字节序模式。
文件
文件的也会存储汉字当然也要进行编码。如果采用UTF-16这样的有字节序模式区分的编码编码规则要求可以在文件头部的BOMByte Order Mark来标记。如果没有标记除非事先知道字节序的模式否则只能大小端都试一遍。