我正在使用 Ruby,并且正在与需要在发送消息本身之前格式化“标头”的网络端点进行通信。
标头中的第一个字段必须是消息长度,它被定义为网络字节顺序中的 2 个二进制字节消息长度。
例如,我的消息长度为 1024。如何将 1024 表示为二进制两字节?
在 Ruby(以及 Perl 和 Python 和...)中进行字节处理的标准工具是pack
和unpack
. Ruby'spack
在Array
. 您的长度应该是两个字节长并且按网络字节顺序排列,这听起来像是n
格式说明符的工作:
n | 整数 | 16 位无符号网络(大端)字节顺序
因此,如果长度为 in length
,您将得到两个字节:
two_bytes = [ length ].pack('n')
如果您需要做相反的事情,请查看String#unpack
:
length = two_bytes.unpack('n').first
请参阅Array#pack。
[1024].pack("n")
这会将数字打包为网络顺序字节序列\x04\x00
。
它的工作方式是每个字节是 8 个二进制位。二进制的 1024 是10000000000
. 如果我们将其分解为 8 个八位字节(每字节 8 位),我们得到:00000100 00000000
.
一个字节可以表示(2 个状态)^(8 个位置)= 256 个唯一值。然而,由于我们没有 256 个 ascii 可打印字符,我们将字节直观地表示为十六进制对,因为十六进制数字可以表示 16 个不同的值,并且 16 * 16 = 256。因此,我们可以取第一个字节,00000100
并打破它成两个十六进制四边形为0000 0100
. 将二进制转换为十六进制给了我们0x04
. 第二个字节是微不足道的,0000 0000
就像0x00
. 这为我们提供了两字节字符串的十六进制表示。
值得注意的是,由于您被限制为 2 字节(16 位)标头,因此您的最大值被限制为11111111 11111111
, 或 2^16 - 1 =65535
字节。任何大于该值的消息都无法准确地以两个字节表示其长度。