以下是工业级高性能 32位整数字节序转换工具类,全面覆盖 Modbus 等工业协议中常见的四种字节序:
四种常见 32 位字节序(ABCD 表示法)
- ABCD:标准 Big-Endian(高字在前,高字节在前)—— 最符合 Modbus 规范
- BADC:Big-Endian + Byte Swap(字内高低字节交换)
- CDAB:Little-Endian + Word Swap(字交换)
- DCBA:标准 Little-Endian(完整反序)
usingSystem;usingSystem.Buffers.Binary;usingSystem.Collections.Generic;usingSystem.Globalization;usingSystem.Runtime.CompilerServices;namespaceIndustrialProtocol{/// <summary>/// 32位整数字节序转换枚举(工业协议常用)/// </summary>publicenumInt32ByteOrder{/// <summary>ABCD - Big-Endian (标准大端,最常见于 Modbus)</summary>ABCD=0,/// <summary>BADC - Big-Endian Byte Swapped</summary>BADC=1,/// <summary>CDAB - Little-Endian Word Swapped</summary>CDAB=2,/// <summary>DCBA - Little-Endian (完整小端)</summary>DCBA=3}/// <summary>/// 工业级 32位整数字节序转换工具类(高性能 + 位运算)/// 支持 string(十六进制) 和 byte[] 两种输入方式/// </summary>publicstaticclassIndustrialInt32ByteOrder{#region核心位运算转换函数/// <summary>/// 对 uint32 执行指定的字节序转换/// </summary>[MethodImpl(MethodImplOptions.AggressiveInlining)]publicstaticuintConvertUInt32(uintvalue,Int32ByteOrderorder){returnorderswitch{Int32ByteOrder.ABCD=>value,// 不变Int32ByteOrder.BADC=>BinaryPrimitives.ReverseEndianness(value),// 字内字节交换Int32ByteOrder.CDAB=>((value&0xFFFF0000U)>>16)|((value&0x0000FFFFU)<<16),// 字交换Int32ByteOrder.DCBA=>BinaryPrimitives.ReverseEndianness(((value&0xFFFF0000U)>>16)|((value&0x0000FFFFU)<<16)),_=>value};}[MethodImpl(MethodImplOptions.AggressiveInlining)]publicstaticintConvertInt32(intvalue,Int32ByteOrderorder){return(int)ConvertUInt32((uint)value,order);}#endregion#region从十六进制字符串解析(每8字符一组)/// <summary>/// 把十六进制字符串解析为 uint32 列表(已完成字节序转换)/// 每8个字符(4字节)为一组,不足时高位补0/// </summary>publicstaticList<uint>ParseToUInt32(stringhexString,Int32ByteOrderbyteOrder=Int32ByteOrder.ABCD){if(string.IsNullOrWhiteSpace(hexString))returnnewList<uint>();hexString=hexString.Replace(" ","").ToUpperInvariant();varresult=newList<uint>(hexString.Length/8+1);for(inti=0;i<hexString.Length;i+=8){stringchunk=hexString.Substring(i,Math.Min(8,hexString.Length-i)).PadLeft(8,'0');if(uint.TryParse(chunk,NumberStyles.HexNumber,CultureInfo.InvariantCulture,outuintbigEndianValue)){uintfinalValue=ConvertUInt32(bigEndianValue,byteOrder);result.Add(finalValue);}else{result.Add(0);}}returnresult;}publicstaticList<int>ParseToInt32(stringhexString,Int32ByteOrderbyteOrder=Int32ByteOrder.ABCD){varuintList=ParseToUInt32(hexString,byteOrder);varintList=newList<int>(uintList.Count);foreach(varuinuintList)intList.Add((int)u);returnintList;}#endregion#region从 byte[] 直接解析(最高性能,推荐真实通信使用)/// <summary>/// 从原始字节数组(Modbus 返回的 byte[])解析 32位整数(已字节序转换)/// </summary>publicstaticuint[]ParseUInt32FromBytes(ReadOnlySpan<byte>data,Int32ByteOrderbyteOrder=Int32ByteOrder.ABCD){if(data.Length<4)returnArray.Empty<uint>();intcount=data.Length/4;varresult=newuint[count];for(inti=0;i<count;i++){intoffset=i*4;// 先组合成 Big-Endian uint(Modbus 单个寄存器为 Big-Endian)uintbigEndian=(uint)((data[offset+0]<<24)|(data[offset+1]<<16)|(data[offset+2]<<8)|(data[offset+3]));result[i]=ConvertUInt32(bigEndian,byteOrder);}returnresult;}#endregion#region辅助方法:返回转换后的十六进制字符串(便于调试)publicstaticList<string>ParseToSwappedHex32(stringhexString,Int32ByteOrderbyteOrder=Int32ByteOrder.ABCD){varvalues=ParseToUInt32(hexString,byteOrder);varhexList=newList<string>(values.Count);foreach(varvinvalues)hexList.Add(v.ToString("X8"));returnhexList;}#endregion#region测试示例publicstaticvoidDemo(){// 测试数据:假设设备发送的原始 hex(两个 32位数)stringinputHex="12345678 9ABCDEF0";// 实际使用时可去掉空格Console.WriteLine("输入 Hex: "+inputHex);foreach(Int32ByteOrderorderinEnum.GetValues(typeof(Int32ByteOrder))){varresults=ParseToUInt32(inputHex.Replace(" ",""),order);Console.WriteLine($"{order,-6}→{string.Join(" ",results.Select(v=>v.ToString("X8")))}");}}#endregion}}使用示例
stringhexData="313239393939450012345678";// 按不同字节序解析varabcd=IndustrialInt32ByteOrder.ParseToUInt32(hexData,Int32ByteOrder.ABCD);varbadc=IndustrialInt32ByteOrder.ParseToUInt32(hexData,Int32ByteOrder.BADC);varcdab=IndustrialInt32ByteOrder.ParseToUInt32(hexData,Int32ByteOrder.CDAB);vardcba=IndustrialInt32ByteOrder.ParseToUInt32(hexData,Int32ByteOrder.DCBA);性能建议:
- 真实 Modbus/TCP 或串口通信时,优先使用
ParseUInt32FromBytes(直接操作byte[]或Span<byte>)。 .NET 5+强烈推荐使用BinaryPrimitives.ReverseEndianness。- 对于高频数据,建议把
byteOrder配置成枚举或配置文件,避免硬编码。
需要我继续扩展32位浮点数(Float / Real)的四种字节序转换版本吗?或者增加64位(long / double)支持?随时告诉我具体需求。