Преобразование строки битов эликсира UTF-16LE в строку эликсира

Учитывая цепочку битов эликсира, закодированную в UTF-16LE:

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

как я могу преобразовать это в читаемую строку эликсира (в ней написано "Разрушитель")? Самое близкое, что я получил, это преобразование вышеупомянутого в список кодовых точек Unicode (["0044", "0065", ...]) и пытается предварять \u escape-последовательность для них, но Elixir выдает ошибку, поскольку это недопустимая последовательность. У меня нет идей.

2 ответа

Решение

Самый простой способ - использовать функции из :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

(в самом конце нулевой байт, поэтому в оболочке будет использоваться двоичный дисплей вместо строки, и в зависимости от ОС он может распечатать дополнительное представление для нулевого байта)

Вы можете использовать сопоставление с образцом Эликсира, в частности, <<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²
Другие вопросы по тегам