2016-09-29 6 views
2

Дано битовая Elixir закодирована в UTF-16LE:Преобразования битовой UTF-16LE Elixir в Elixir Струнного

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

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

+0

Вы» ve уже [ответил] (http://stackoverflow.com/a/39601246/3102718) этот вопрос, не так ли? –

+0

Это временный взлом, и для более сложных ситуаций, например. разбор строки неизвестной длины, которая заканчивается нулевым байтом, недостаточно. – user701847

+0

Хорошо, спасибо, просто было любопытно. –

ответ

5

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

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

+0

А, ничего себе ... Я действительно посмотрел в библиотеках Erlang, в частности «двоичный», чтобы узнать, поможет ли мне какой-либо из этих методов, но полностью пренебрег прокруткой страницы и просмотром Unicode ... спасибо! – user701847

+1

Это приятно! Я не знал ': unicode.characters_ *' функции также принимали двоичные файлы. @ user701847, вы, вероятно, должны принять этот ответ вместо моего. – Dogbert

1

Вы можете использовать поиск по шаблону эликсира, в частности <<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² 
+1

А, это то, чего мне не хватало, спасибо! Я никогда не принимал 'codepoint', а затем сопоставлял его как' codepoint :: utf8'; Я в основном не знал, что делать с 2 байтами. Чтобы сделать ваш еще проще, мы можем просто сделать: 'для << codepoint :: utf16-little <- binary >>, в:" ", do: << codepoint :: utf8>' – user701847