5

给定一个以 UTF-16LE 编码的 Elixir 位串:

<<68, 0, 101, 0, 118, 0, 97, 0, 115, 0, 116, 0, 97, 0, 116, 0, 111, 0, 114, 0, 0, 0>>

我怎样才能把它转换成可读的 Elixir 字符串(它拼写为“Devastator”)?我得到的最接近的是将上面的内容转换为 Unicode 代码点 ( ["0044", "0065", ...]) 列表并尝试在\u它们前面加上转义序列,但 Elixir 会抛出错误,因为它是无效序列。我没主意了。

4

2 回答 2

8

最简单的方法是使用:unicode模块中的函数:

:unicode.characters_to_binary(utf16binary, {:utf16, :little})

例如

<<68, 0, 101, 0, 118, 0, 97, 0, 115, 0, 116, 0, 97, 0, 116, 0, 111, 0, 114, 0, 0, 0>>
|> :unicode.characters_to_binary({:utf16, :little})
|> IO.puts
#=> Devastator

(最后有一个空字节,因此在 shell 中将使用二进制显示而不是字符串,并且根据操作系统,它可能会为空字节打印一些额外的表示)

于 2016-09-29T15:01:31.127 回答
1

您可以使用 Elixir 的模式匹配,特别是<<codepoint::utf16-little>>

defmodule Convert do
  def utf16le_to_utf8(binary), do: utf16le_to_utf8(binary, "")

  defp utf16le_to_utf8(<<codepoint::utf16-little, rest::binary>>, acc) do
    utf16le_to_utf8(rest, <<acc::binary, codepoint::utf8>>)
  end
  defp utf16le_to_utf8("", acc), do: acc
end

<<68, 0, 101, 0, 118, 0, 97, 0, 115, 0, 116, 0, 97, 0, 116, 0, 111, 0, 114, 0, 0, 0>>
|> Convert.utf16le_to_utf8
|> IO.puts

<<192, 3, 114, 0, 178, 0>>
|> Convert.utf16le_to_utf8
|> IO.puts

输出:

Devastator
πr²
于 2016-09-29T14:50:22.777 回答