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

在Elixir中解析字节标志位:十六进制字节转标志列表方法

没问题,我来一步步教你怎么把十六进制字节转成对应的标志列表!你已经搞定了十六进制转整数的步骤,剩下的位操作其实很简单,咱们慢慢说~

解决思路和步骤

1. 先定义标志与位位置的映射表

这一步可是核心!因为后续要把标志改成描述性名称时,只需要动这里,完全不用碰逻辑代码。这里要注意:位是从右往左数的,最右边的是第0位,和你给出的例子完全匹配。

比如用Elixir的话可以这么定义(如果你用其他语言,思路完全一致,只是语法稍有不同):

# 后续直接把:flagX改成描述性名称就行,比如:allow_upload, :enable_debug
@flag_mappings [
  {:flag0, 0},
  {:flag1, 1},
  {:flag2, 2},
  {:flag3, 3},
  {:flag4, 4},
  {:flag5, 5},
  {:flag6, 6},
  {:flag7, 7}
  # 如果是两个完整字节(16位),继续加{:flag8, 8}直到{:flag15, 15}就好
]

2. 十六进制转整数(你已经掌握啦)

就用你提到的方法把十六进制字符串转成整数:

integer = String.to_integer("0c", 16) # 得到12,对应二进制00001100
integer = String.to_integer("31", 16) # 得到49,对应二进制00110001

3. 用位操作筛选已设置的标志

关键就是用按位与操作来检查每一位是否被设置:

  • 对每个标志对应的位位置bit,计算1 <<< bit(把数字1左移bit位,得到只有该位为1的整数)
  • 把这个数和我们的目标整数做按位与(&&&),如果结果不等于0,说明该位是1,对应的标志已被设置

完整的函数示例:

def hex_to_flags(hex_str) do
  integer = String.to_integer(hex_str, 16)
  
  @flag_mappings
  # 筛选出位被设置的标志项
  |> Enum.filter(fn {_flag_name, bit_position} ->
    (integer &&& (1 <<< bit_position)) != 0
  end)
  # 只提取标志名称
  |> Enum.map(fn {flag_name, _bit_position} -> flag_name end)
end

测试你的例子

  • 调用hex_to_flags("0c")会返回[:flag2, :flag3](顺序不影响,如果你想要从高位到低位排序,可以加个|> Enum.sort_by(fn flag -> ... end)调整)
  • 调用hex_to_flags("31")会返回[:flag0, :flag4, :flag5],和你的例子[:flag5, :flag4, :flag0]只是顺序不同,逻辑上完全一致

后续改标志名称的小技巧

比如你想把:flag2改成:enable_logging,:flag3改成:allow_edit,只需要修改映射表:

@flag_mappings [
  {:flag0, 0},
  {:flag1, 1},
  {:enable_logging, 2},
  {:allow_edit, 3},
  {:flag4, 4},
  {:flag5, 5},
  {:flag6, 6},
  {:flag7, 7}
]

这样调用hex_to_flags("0c")就会直接返回[:enable_logging, :allow_edit],完全不用改逻辑代码,非常方便!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:55:07