【问题标题】:Network Byte[] to Int64 problems网络字节 [] 到 Int64 问题
【发布时间】:2019-10-16 23:10:06
【问题描述】:

我正在一个非常旧的系统上从多播流中收集二进制信息。我已经转换了大部分,但我遇到了高/低 DWORD 组合的问题。我写了一个小测试应用程序来尝试解决这个问题。我被告知该值应在 30XXX 范围内。

给我的文档说它被定义为...

DWORD ID_HIGH;
DWORD ID_LOW;

到目前为止,我只是得到垃圾。我尝试了位移位和许多其他路线。到目前为止,没有运气。感谢您提供任何帮助。

static void Main(string[] args)
        {            
            byte[] data = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x04, 0x51};

            Int32 ID_High = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 0));
            Int32 ID_Low = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 4));
            Int64ToInt32 i6;
            i6.Int64Value = 0;
            i6.LeftInt32 = ID_High;
            i6.RightInt32 = ID_Low;


        }

        [StructLayout(LayoutKind.Explicit)]
        struct Int64ToInt32
        {
            [FieldOffset(0)]
            public Int64 Int64Value;
            [FieldOffset(0)]
            public Int32 LeftInt32;
            [FieldOffset(4)]
            public Int32 RightInt32;
        }

了解更多信息。这是从多播接收到的整个 byte[]。

byte[] data = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x04, 0x51, 0x00, 0x00, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x04, 0x50, 0x00, 0x00, 0x04, 0x7F,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x90, 0x3E, 0xE4, 0x62, 0xB8, 0xB1, 0x4D, 0xB0, 0xF1, 0x15, 0x94,
                            0xF1, 0x13, 0x0F, 0x84, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 };

这是它应该翻译成的定义。

typedef struct
{
    DWORD AgentID_High; // Agent phoneset login ID high-order 32 bits
    DWORD AgentID_Low; // Agent phoneset login ID low-order 32 bits
    DWORD State;
    DWORD SupervisorID_High; // Supervisor phoneset login ID high-order 32 bits
    DWORD SupervisorID_Low; // Supervisor phoneset login ID low-order 32 bits
    DWORD TimeInState;
    DWORD AnsweringSkillset;
    DWORD DNInTimeInState;
    DWORD DNOutTimeInState;
    BYTE SupervisorUserID[16];
    DWORD PositionID;
    // TM26314
    DWORD NotReadyReasonCode_High;
    DWORD NotReadyReasonCode_Low;
    DWORD DNOutCallNumber_High;
    DWORD DNOutCallNumber_Low;
    DWORD SkillsetCallAnswered;
    DWORD DNInCallAnswered;
    DWORD DNOutCallMade;
    //Q00635846 griffinn MIROS Changes
    DWORD AnsweringApplication;
    DWORD AnsweringCDN_High;
    DWORD AnsweringCDN_Low;
    DWORD AnsweringDNIS_High;
    DWORD AnsweringDNIS_Low;
} NIMultiCastAgentRecord_Rls5; // size = 104 bytes

仅使用 IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 0)); 即可解析所有其他 DWORDS 除了这些分裂的词。我个人认为数据似乎不正确,但我想要第二意见。

**最新开发..据我所知,代理 ID 是 30451。 如果您查看十六进制位,它就在十六进制中。

byte[] data = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0x04, 0x51};

所以这就是我想出的。我觉得我在这里打破了各种规则......

string AgentID = BitConverter.ToString(data);
AgentID = AgentID.Replace("-", "").Replace("F", "");

【问题讨论】:

  • 在网络顺序中,作为有符号的 32 位整数,fff30451 将是 -850863,而前面的四个 ff 值只是符号扩展64 位。这远不及 3 万(假设这就是 30XXX 的意思)。
  • 另外,i6.LeftInt32 应该从 ID_Low 分配,低位从 [4] 到 [7]。
  • IPAddress 具有采用 64 位值的方法重载。尝试 IPAddress.NetworkToHostOrder(BitConverter.ToInt64(data, 0))` 。一旦您的数据符合您的期望,就应该在没有显式布局结构的情况下处理它。
  • 这里没有足够的信息来告诉您出了什么问题。但是,您提供的数据看起来不像 30000 到 30999 范围内的任何数字,甚至不是 0x30000 到 0x30fff 范围内的任何数字。即使我们取最小的字节并将其设为最重要的字节,这也会给我们一个大于 67,000,000 的数字。如果您可以说出这些字节应该代表什么确切,那么弄清楚它们是如何编码的将是微不足道的。没有这些信息,任何人都只能猜测。
  • 添加了更多信息,希望对您有所帮助。我同意这些数据看起来根本不适合这些。我认为它不应该以 4x 0xFF 开头。自从我处理这种事情以来已经有一段时间了,所以我正在寻求其他意见。

标签: c# byte bitconverter


【解决方案1】:

您说它是“30XXX”范围内的值 - 所以30,00030,999

Decimal    Hex big-endian    Hex little-endian
30000           0x75 0x30            0x30 0x75
30999           0x79 0x17            0x17 0x79

因此,无论如何,我们都在寻找0x750x79 范围内的至少一个字节,无论它是 16 位、32 位还是 64 位大小,都将存在整数,也不管它是大端还是小端。

您发布的所有字节都不在该范围内 - 因此这些值中​​的任何一个都不可能使用普通整数表示 30,000 到 30,999 范围内的值。

【讨论】:

  • 如果我翻转位,我会得到一个正确范围内的数字。 (按位非)但我为什么要这样做?
  • @Steve:“如果我翻转位,我会得到一个正确范围内的数字”——你怎么看出来的?将您的数据解释为已签名,它代表-850863(2 的补码)。取反会得到 850863。如果您将这些位视为 1 的补码,而只是翻转这些位,则结果为 850862。这些值都不接近 30000(十进制)。你是说你描述的“范围”是十六进制的吗?如果是这样,如果您在问题中明确说明,那肯定会好得多。
  • 我应该在凌晨 1 点停止回答。我只是想在这里找到一些理由。所以我所做的是... FF FF FF FF | FF F3 04 51 -> 1111 1111 x4 | 1111 1111 1111 0011 0000 0100 0101 0001 -> 0000 0000 | 0000 0000 0000 1100 1111 1011 1010 1110 = 850,862 然后倒过来读 0111 0101 1101 1111 = 30,175.. 但这忽略了最后一个 0011,我昨晚没有注意到。我猜纯粹是机会。只是因为他们发誓他们的数据没有问题而感到沮丧。我也用 Wireshark 验证了我的 byte[] 并且它始终输出相同的东西。
  • @vSteve 所以数据是按位NOT 按位翻转的?笏? (例如,给定0x59NOT( 0x59 ) == ( 0xA6 == 1010 0110b ) 然后将字节中位的顺序反转为0110 0101 == 0x65。这太疯狂了。
  • 是的,是的。这一切都归结为一个简单的问题。我是在解析这些东西时遗漏了一步还是数据 FUBAR。
猜你喜欢
  • 2014-05-18
  • 2011-03-06
  • 1970-01-01
  • 2015-06-02
  • 2016-03-30
  • 1970-01-01
  • 2017-05-23
  • 2016-03-15
  • 2019-12-18
相关资源
最近更新 更多