解析LIFX标头会返回错误的协议编号

Rya*_*igg 5 elixir

我试图根据他们的文档解析LIFX标头.

这是我的代码:

data = <<36, 0, 0, 52, 33, 235, 176, 178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0>>
<< size :: little-integer-size(16),
   origin :: little-integer-size(2),
   tagged :: size(1),
   addressable :: size(1),
   protocol :: little-integer-size(12),
   rest :: bitstring >> = data
IO.puts protocol
Run Code Online (Sandbox Code Playgroud)

这告诉我的protocol1027,但是LIFX的文档说它应该是1024.我已经通过使用LIFX的RubyGem确认该字段的值是1024.

为什么在Elixir中我看到这个值为1027而不是1024?

Gaz*_*ler 3

我不是这方面的专家,但我有一个理论,即当您采用 12 位而不是 16 位时,字节序并不会按照您期望的方式工作。这个解决方案只是我在玩弄数字,因为我发现它很有趣问题。可能有更好的解决方案,我还没有深入研究 erlang 实现。

如果我们忽略所有其他数据,那么我们会得到:

data = <<0, 52>>

# data is equal to 0000 0000 0011 0100
#                  oota pppp pppp pppp

<< origin :: little-integer-size(2),
   tagged :: size(1),
   addressable :: size(1),
   protocol :: little-integer-size(12) >> = data

IO.puts protocol     # 1027
IO.puts origin       # 0
IO.puts tagged       # 0
IO.puts addressable  # 0

# doing little-endiain on 12 bits = 0100 0000 0011
#                                   pppp pppp pppp
Run Code Online (Sandbox Code Playgroud)

由于这是小端字节序,如果我们交换两个字节,我们会得到:

data = <<52, 0>>

# data is equal to 0011 0100 0000 0000
#                  oota pppp pppp pppp

<< origin :: integer-size(2),
   tagged :: size(1),
   addressable :: size(1),
   protocol :: integer-size(12) >> = data

IO.puts protocol     # 1024
IO.puts origin       # 0
IO.puts tagged       # 1
IO.puts addressable  # 1
Run Code Online (Sandbox Code Playgroud)

所以一种解决方案是:

data = <<0, 52>>
<< p1 :: integer-size(4),
   p2 :: integer-size(4),
   << origin :: size(2), tagged :: size(1), addressable :: size(1) >>,
   p3 :: integer-size(4) >> = data

IO.inspect p1        # 0
IO.inspect p2        # 0
IO.inspect p3        # 4
<< protocol :: size(12) >> = <<p3 :: size(4), p2 :: size(4), p1 :: size(4)>>
IO.puts protocol     # 1024
IO.puts origin       # 0
IO.puts tagged       # 1
IO.puts addressable  # 1
Run Code Online (Sandbox Code Playgroud)