Elixir: 对TTN消息进行Base64解码

3

目标:

我从物联网获取一个base64编码的原始有效负载。我正在尝试在我的服务器上解码它,而不是使用他们的javascript有效负载解码器。

十六进制编码的消息是:AWYQkQCsCPMANA==

已实现功能:

我的常规解码方法如下:

def decode(string) do
  string = String.upcase(string)
  # get the first 2 bytes, which is 4 hex characters
  {flagsbat, string} = String.split_at(string, 4)
  parse(Base.decode16!(flagsbat), string)
end

实际解码器的函数头:

defp parse(<<a::1, b::1, _reserve::1, c::1, d::1, e::1, f::1, g::1, bat>>, <<data::binary>>) do

对于像"01660dfa0109038d0030"这样的字符串,该部分功能正常。但是当TTN向我发送Base64编码的原始有效载荷时,一切都失败了。

出了什么问题:

我试图调用函数Base.decode64!(raw_payload) |> decode(), 它给出错误:** (ArgumentError) non-alphabet digit found: "\x01" (byte 1)

有趣的是,我发现如果我执行Base.decode64!("AWYQkQCsCPMANA=="),我会得到<<1, 102, 16, 145, 0, 172, 8, 243, 0, 52>>,而https://cryptii.com/pipes/base64-to-hex返回01 66 10 91 00 ac 08 f3 00 34。为什么?

编辑: 为了澄清:

{flagsbat, string} = "AWYQkQCsCPMANA==" |> Base.decode64!() |> String.upcase() |> String.split_at(4)
Base.decode16!(flagsbat) # this throws the error


{flagsbat, string} = "0166109100ac08f30034" |> String.upcase() |> String.split_at(4)
Base.decode16!(flagsbat) # works

那么,如何从进行了 Base64 编码的原始负载中获取可拆分和解析的字符串呢?
"0166109100ac08f30034" 是我在 https://cryptii.com/pipes/base64-to-hex 上对 "AWYQkQCsCPMANA==" 进行 Base64 解码后得到的。

1
Elixir 以十进制打印二进制文件,但 cryptii.com 的结果是十六进制的。请尝试 for <<i <- <<1, 102, 16, 145, 0, 172, 8, 243, 0, 52>> >>, do: Integer.to_string(i, 16) - Adam Millerchip
@AdamMillerchip:这不就是Base.encode16吗? - Joe Eifert
它们不是等价的,但是它们都转换为十六进制,是的。 - Adam Millerchip
1个回答

3
原来我需要对解码的Base64进行Base16编码才能得到实际的字符串。
Base.decode64!("AWYQkQCsCPMANA==") |> Base.encode16() |> decode()

那就可以了,我可以顺利地将它传递到解码函数中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接