You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修正ParseLocation函数的字节序(Endianess)错误?

问题描述

我正在解析一些数据,现有ParseLocation函数可正常运行,但存在字节序(Endianess)错误。例如当字节数组为:

Dim bytes As Byte() = {3, 7}

时,我期望得到结果0x0307,实际却得到0x0703,更大的变量也存在同样问题。以下是该函数代码:

Function ParseLocation(data As Byte()) As Dictionary(Of String, Object)
    Dim datasheet As New Dictionary(Of String, Object)()

    ' 从buffer 'data'读取并赋值到'datasheet'
    datasheet("startBit") = BitConverter.ToUInt16(data, 0)
    datasheet("protocolLength") = data(2)
    datasheet("protocolNumber") = data(3)
    datasheet("fixTime") = data.Skip(4).Take(6).ToArray() ' 从位置4开始取6字节
    datasheet("quantity") = data(10)
    datasheet("lat") = BitConverter.ToUInt32(data, 11)
    datasheet("lon") = BitConverter.ToUInt32(data, 15)
    datasheet("speed") = data(19)
    datasheet("course") = BitConverter.ToUInt16(data, 20)
    datasheet("mcc") = BitConverter.ToUInt16(data, 22)
    datasheet("mnc") = data(24)
    datasheet("lac") = BitConverter.ToUInt16(data, 25)
    datasheet("cellId") = Convert.ToInt32(BitConverter.ToString(data, 27, 3).Replace("-", ""), 16)
    datasheet("serialNr") = BitConverter.ToUInt16(data, 30)
    datasheet("errorCheck") = BitConverter.ToUInt16(data, 32)

    Return datasheet
End Function

请问该如何修复这个字节序错误?


修复方案

问题核心是数据采用大端字节序(Big-Endian)存储,但BitConverter默认使用当前系统的字节序(通常为小端Little-Endian),导致转换时字节顺序被反转。以下是具体修复方法:

1. 封装大端字节序转换工具函数

先编写通用的大端转换函数,替代BitConverter的默认逻辑:

' 大端字节序转UInt16
Function BigEndianToUInt16(bytes As Byte(), offset As Integer) As UInt16
    Dim segment = bytes.Skip(offset).Take(2).ToArray()
    If BitConverter.IsLittleEndian Then
        Array.Reverse(segment)
    End If
    Return BitConverter.ToUInt16(segment, 0)
End Function

' 大端字节序转UInt32
Function BigEndianToUInt32(bytes As Byte(), offset As Integer) As UInt32
    Dim segment = bytes.Skip(offset).Take(4).ToArray()
    If BitConverter.IsLittleEndian Then
        Array.Reverse(segment)
    End If
    Return BitConverter.ToUInt32(segment, 0)
End Function

' 处理3字节的CellId(大端转Int32)
Function BigEndian3BytesToInt32(bytes As Byte(), offset As Integer) As Integer
    ' 3字节大端数据补高位0,转为4字节大端后处理
    Dim extendedBytes = New Byte() {0, bytes(offset), bytes(offset+1), bytes(offset+2)}
    If BitConverter.IsLittleEndian Then
        Array.Reverse(extendedBytes)
    End If
    Return BitConverter.ToInt32(extendedBytes, 0)
End Function

2. 修改原函数使用大端转换逻辑

将原函数中所有多字节转换的代码替换为上述工具函数:

Function ParseLocation(data As Byte()) As Dictionary(Of String, Object)
    Dim datasheet As New Dictionary(Of String, Object)()

    datasheet("startBit") = BigEndianToUInt16(data, 0)
    datasheet("protocolLength") = data(2)
    datasheet("protocolNumber") = data(3)
    datasheet("fixTime") = data.Skip(4).Take(6).ToArray()
    datasheet("quantity") = data(10)
    datasheet("lat") = BigEndianToUInt32(data, 11)
    datasheet("lon") = BigEndianToUInt32(data, 15)
    datasheet("speed") = data(19)
    datasheet("course") = BigEndianToUInt16(data, 20)
    datasheet("mcc") = BigEndianToUInt16(data, 22)
    datasheet("mnc") = data(24)
    datasheet("lac") = BigEndianToUInt16(data, 25)
    datasheet("cellId") = BigEndian3BytesToInt32(data, 27)
    datasheet("serialNr") = BigEndianToUInt16(data, 30)
    datasheet("errorCheck") = BigEndianToUInt16(data, 32)

    Return datasheet
End Function

关键说明

  • BitConverter.IsLittleEndian用于判断当前系统字节序,仅在小端系统下反转字节,保证代码跨系统兼容。
  • 针对3字节的cellId,通过补高位0转为4字节大端数据后处理,避免直接字符串拼接导致的字节序错误。

内容的提问来源于stack exchange,提问作者E_Blue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:35:17