了解网络、十六进制和ascii如何交互 我最近被分配到一个C++项目,涉及通过UDP在计算机之间发送信息。当数据包到达时,我有一个程序,它接受数据并可以将其显示为原始十六进制字符串。然而,我很难准确地理解整个过程应该如何工作。十六进制字符串可能包含多个字段(例如,一个4字符数组、一些float_32s和一些uint_32s)

了解网络、十六进制和ascii如何交互 我最近被分配到一个C++项目,涉及通过UDP在计算机之间发送信息。当数据包到达时,我有一个程序,它接受数据并可以将其显示为原始十六进制字符串。然而,我很难准确地理解整个过程应该如何工作。十六进制字符串可能包含多个字段(例如,一个4字符数组、一些float_32s和一些uint_32s),c++,udp,hex,ascii,C++,Udp,Hex,Ascii,如何将此字符串的部分转换为正确的变量类型?第一个值是ASCII标题,非常简单;十六进制字符串中的前八个字符是ASCII字的十六进制表示形式(0x45十六进制可直接转换为大写字母E)。但是下一个值,32位浮点,对我来说没有意义。十六进制值“42 01 33 33”和浮点值“32.3”(给定示例)之间的关系是什么 在这里我有点不知所措,我觉得我缺少了一些有关数字系统工作方式的基本信息。C中的所有类型都有一个表示(对于大多数类型,它是由特定的实现定义的)。大多数C实现用于表示浮式(这实际上是C和C++

如何将此字符串的部分转换为正确的变量类型?第一个值是ASCII标题,非常简单;十六进制字符串中的前八个字符是ASCII字的十六进制表示形式(0x45十六进制可直接转换为大写字母E)。但是下一个值,32位浮点,对我来说没有意义。十六进制值“42 01 33 33”和浮点值“32.3”(给定示例)之间的关系是什么


在这里我有点不知所措,我觉得我缺少了一些有关数字系统工作方式的基本信息。

C中的所有类型都有一个表示(对于大多数类型,它是由特定的实现定义的)。大多数C实现用于表示浮式(这实际上是C和C++的要求,但从内存中看它不是)。维基百科的文章解释了浮动类型在内存中的表示方式。在大多数C和C++实现中,<代码>浮点< /C> >是32位类型,<代码>双是64位类型。因此,在这些实现中,
float
是4字节宽,
double
是8字节宽

小心,因为字节顺序可能不同。有些体系结构将浮动类型存储在little endian中,有些存储在big endian中。维基百科上也有一篇关于这个问题的文章

要将字节复制到浮动类型,必须确保浮动类型的大小与所拥有的字节数相同,然后可以将字节逐个“复制”到浮动类型中。类似这样的东西会告诉你它的要点:

unsigned char rep[] = { 0x42, 0x01, 0x33, 0x33 };
float someFloat;

if (sizeof(someFloat) == 4)
{
    memcpy(&someFloat, rep, sizeof(someFloat));
}
else
{
    // throw an exception or something
}

还有其他方法可以将字节复制到浮动类型,但要小心“违反规则”(类型双关等)。此外,如果结果值不正确,可能是因为字节顺序错误,因此需要反向复制字节,以便表示中的第四个字节是浮点的第一个字节。

如果有十六进制值:

42 01 33 33
它相当于

0100 0010 0000 0001 0011 0011 0011 0011
在二进制代码中

现在,有一个名为的浮点标准,它告诉您如何将浮点数格式化为二进制或向后

它的要点是第一位是符号(正数/负数),接下来的8位是指数,最后的23位是尾数。这就是计算机内部保存浮点数的方式,因为它只能存储1和0


如果按照IEEE规定的方式将所有数据相加,则得到32.3。

确切的数据格式由所用协议指定,但表示数字数据的常用方法有:

无符号整数:这实际上是最简单的。它的典型表示原理上与我们的普通十进制系统类似,只是“数字”是字节,可以有256个不同的值

如果你看一个像3127这样的十进制数,你会看到三位数。最低有效位是最后一位(本例中为7)。最不重要的意思是,如果将其更改为1,则得到值的最小更改(即1)。示例中最有效的数字是最左边的3:如果将该数字更改为1,则该值的最大更改量为1000。因为有10个不同的数字(0到9),所以由“3127”表示的数字是3*10*10*10+1*10*10+2*10+7。请注意,itz只是一种约定,即最重要的数字排在第一位;您还可以定义最低有效数字排在第一位,然后将该数字写为“7213”

现在,在大多数编码中,无符号数字的工作原理完全相同,只是“数字”是字节,因此我们使用的是基数256,而不是基数10。此外,与十进制数字不同,没有统一的约定,最高有效字节(MSB)还是最低有效字节(LSB)排在第一位;这两种约定在不同的协议或文件格式中使用

例如,在具有MSB优先的4字节(即32位)无符号整数(也称为big-endian编码)中,值1000=0*256^3+0*256^2+3*256+232将由四个字节的值
0、0、3、232
或十六进制
00 03 E8
表示。对于小端编码(LSB优先),它将改为
E8 03 00
。作为16位整数,它将是
03e8
(大端)或
e803
(小端)

对于有符号整数,最常用的表示形式是二的补码。基本上,这意味着,如果最高有效位为1(即最高有效字节为128或更大),字节序列不会对上述数字进行编码,而是从中减去2^(位)得到负数,其中(位)是数字中的位数。例如,在有符号16位整数中,序列
FF FF
不像在16位无符号整数中那样是65535,而是65535-2^16=-1。与无符号整数一样,您必须区分big-endian和little-endian。例如,-3将是16位小尾数形式的
FF-FD
,但在16位小尾数形式的
FD-FF

浮点运算要复杂得多;目前通常使用IEEE/IEC规定的格式。基本上,浮点数的形式是符号*(1.尾数)*2^指数,符号、尾数和指数存储在不同的子字段中。同样,还有小端和大端形式。

十六进制字符串不是“原始的”。相反,它是原始二进制数据的十六进制表示。阅读ab