C# 小端转大端 Little Endian to Big Endian
什么是大端和小端
Big-Endian和Little-Endian的定义如下:
1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
2) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
举一个例子,比如数字0x12 34 56 78在内存中的表示形式为:
1)大端模式:
低地址 -----------------> 高地址
0x12 | 0x34 | 0x56 | 0x78
2)小端模式:
低地址 ------------------> 高地址
0x78 | 0x56 | 0x34 | 0x12
可见,大端模式和字符串的存储模式类似。
3)下面是两个具体例子:
16bit宽的数0x1234在Little-endian模式(以及Big-endian模式)CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址 小端模式存放内容 大端模式存放内容
0x4000 0x34 0x12
0x4001 0x12 0x34
32bit宽的数0x12345678在Little-endian模式以及Big-endian模式)CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址 小端模式存放内容 大端模式存放内容
0x4000 0x78 0x12
0x4001 0x56 0x34
0x4002 0x34 0x56
0x4003 0x12 0x78
方法1
#region 方法1
public uint Big2Lit(uint zhi)
{
uint tmp;
tmp = ((zhi & 0x000000FF) << 24) +
((zhi & 0x0000FF00) << 8) +
((zhi & 0x00FF0000) >> 8) +
((zhi & 0xFF000000) >> 24);
return tmp;
}
private void button1_Click(object sender, EventArgs e)
{
uint zhi = 0x12345678;
Console.WriteLine("zhi = 0x{0:x} 反转 = 0x{1:x}", zhi, Big2Lit(zhi));
}
#endregion
输出结果
zhi = 0x12345678 反转 = 0x78563412
方法2
#region 方法2
public uint Big2Lit_2(uint zhi)
{
byte[] bt = new byte[4];
bt = BitConverter.GetBytes(zhi);
//交换顺序
byte[] bt2 = new byte[4];
bt2[0] = bt[3];
bt2[1] = bt[2];
bt2[2] = bt[1];
bt2[3] = bt[0];
return BitConverter.ToUInt32(bt2, 0);
}
private void button2_Click(object sender, EventArgs e)
{
uint zhi = 0x12345678;
Console.WriteLine("zhi = 0x{0:x} 反转 = 0x{1:x}", zhi, Big2Lit_2(zhi));
}
#endregion
方法3
#region 方法3
//定义4位联合体
[StructLayout(LayoutKind.Explicit, Size = 4)]
struct UninoCSharp
{
//设置联合体的每一位
[FieldOffset(0)]
public byte b0;
[FieldOffset(1)]
public byte b1;
[FieldOffset(2)]
public byte b2;
[FieldOffset(3)]
public byte b3;
//得到对应的int值
[FieldOffset(0)]
public int IntByte;
//得到对应的uint值
[FieldOffset(0)]
public uint UintByte;
//得到对应的float值
[FieldOffset(0)]
public float Fp32Byte;
}
public uint Big2Lit_3(uint zhi)
{
UninoCSharp tmp;
tmp.b0 = 0; //避免编译警告
tmp.b1 = 0;//避免编译警告
tmp.b2 = 0;//避免编译警告
tmp.b3 = 0;//避免编译警告
tmp.UintByte = zhi;
UninoCSharp tmp2;
tmp2.UintByte = 0;//避免编译警告
tmp2.b3 = tmp.b0;
tmp2.b2 = tmp.b1;
tmp2.b1 = tmp.b2;
tmp2.b0 = tmp.b3;
return tmp2.UintByte;
}
private void button3_Click(object sender, EventArgs e)
{
uint zhi = 0x12345678;
Console.WriteLine("zhi = 0x{0:x} 反转 = 0x{1:x}", zhi, Big2Lit_3(zhi));
}
#endregion
输出
zhi = 0x12345678 反转 = 0x78563412
总结:
推荐使用方法2
理由:具有普适性,并且支持数据类型广泛。
参考链接
C#中C联合Union的实现_c#联合体-CSDN博客https://blog.csdn.net/anlog/article/details/128961676
特此记录
anlog
2024年5月28日