0000 1100 -> [:flag3, :flag2] "3-6ren">
gpt4 book ai didi

elixir - 从 Elixir 中的字节解析标志

转载 作者:行者123 更新时间:2023-12-02 08:07:43 29 4
gpt4 key购买 nike

我有两个十六进制格式的字节,例如“0c”或“31”。如何将其映射到一些标志值?我想要一个所有已设置标志的列表。

例子:

"0c" -> 0000 1100 -> [:flag3, :flag2]
"31" -> 0011 0001 -> [:flag5, :flag4, :flag0]

这里每个标志都由它的位置命名,但后来我想要具有更多描述性名称的标志。

从十六进制获取很容易,只需 String.to_integer("0c", 16),但之后我迷失在 Bitwise 的世界中。

最佳答案

我会选择二进制模式匹配:

级别“简单”。只是模式匹配。

<<i1::1,i2::1,i3::1,i4::1,i5::1,i6::1,i7::1,i8::1>> =
<<String.to_integer("0c", 16)>>
#⇒ "\f"
{i1,i2,i3,i4,i5,i6,i7,i8}
#⇒ {0, 0, 0, 0, 1, 1, 0, 0}

是的,我们已经将所有标志(为简短起见,在上面命名为 i)都映射出来了。

将它们转换为 :flagN 原子列表:

[i1,i2,i3,i4,i5,i6,i7,i8]
|> Enum.reverse()
|> Enum.with_index()
|> Enum.reduce([], fn
{0, _}, acc -> acc
{_, idx}, acc -> [:"flag#{idx}" | acc]
end)
[:flag3, :flag2]

“中级”级别。创建一个接受 String 并生成元组的函数。

def flags(input) do
# possibly some checks of input to fail fast
<<i1::1,i2::1,i3::1,i4::1,i5::1,i6::1,i7::1,i8::1>> =
<<String.to_integer(input, 16)>>
{i1,i2,i3,i4,i5,i6,i7,i8}
end

“高级”级别。生成一个宏,它将为任何长度的输入生成函数(或者直接在模块的主体中​​生成函数。)

defmodule Flags do
Enum.each(1..10, fn i ->
# generate a function for `String`s of length 1–10 here
end)
end

奖励轨道。flag0 .. flag7 变量导出到当前上下文绕过 macros hygiene :

defmodule Flags do
defmacro flags(input) do
mapper =
{:<<>>, [],
0..7
|> Enum.map(& {:::, [], [{:var!, [context: Elixir, import: Kernel],
[{:"flag#{&1}", [], Elixir}]}, 1]})
|> Enum.reverse()
}
quote do
unquote(mapper) = <<String.to_integer(unquote(input), 16)>>
end
end
end

defmodule Flags.Test do
import Flags

def test do
flags("0c")

[flag0,flag1,flag2,flag3,flag4,flag5,flag6,flag7]
|> Enum.with_index()
|> Enum.reduce([], fn
{0, _}, acc -> acc
{_, idx}, acc -> [:"flag#{idx}" | acc]
end)
|> IO.inspect(label: "Result")
IO.inspect(flag2, label: "Flag2")
end
end

Flags.Test.test
#⇒ Result: [:flag3, :flag2]
# Flag2: 1

在后一个例子中,有 局部变量 flagN 在调用 flags("0c")

关于elixir - 从 Elixir 中的字节解析标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49971029/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com