У меня есть данные в кодировке UTF-8, которые находятся в диапазоне элементов Uint8Array в Javascript. Есть ли эффективный способ декодировать их в обычную строку javascript (я считаю, что Javascript использует 16-битный Unicode)? Я не хочу добавлять по одному символу за раз, так как конкатернация строк будет сильно загружать процессор.
javascript
Джек Вестер
источник
источник
u8array.toString()
при чтении файлов из BrowserFS, которые открывают объект Uint8Array при вызовеfs.readFile
.toString
приUint8Array
возврате чисел, разделенных запятыми, таких как"91,50,48,49,57,45"
(Chrome 79)Ответы:
TextEncoder
иTextDecoder
из стандарта Encoding , который полифицируется библиотекой строкового кодирования , преобразует строки в ArrayBuffers:источник
npm install text-encoding
,var textEncoding = require('text-encoding'); var TextDecoder = textEncoding.TextDecoder;
. Нет, спасибо.utf-8
. Итак,TextEncoder
аргумент излишний!TextEncoder
/TextDecoder
API в v11, поэтому нет необходимости устанавливать какие-либо дополнительные пакеты, если вы нацелены только на текущие версии Node.Это должно работать:
Он несколько чище, чем другие решения, потому что не использует никаких хаков и не зависит от функций браузера JS, например, работает также в других средах JS.
Посмотрите демонстрацию JSFiddle .
Также см. Связанные вопросы: здесь и здесь
источник
fromUTF8Array([240,159,154,133])
fromUTF8Array([226,152,131])→"☃"
Вот что я использую:
источник
RangeError
к увеличению текста. «SCRIPT28: Out of stack space
когда я кормлю его 300 + k символов илиRangeError
для Chrome 39. Firefox 33 в порядке. 100 + k работает нормально со всеми тремя.Найдено в одном из примеров приложений Chrome, хотя оно предназначено для больших блоков данных, в которых вас устраивает асинхронное преобразование.
источник
В Node «
Buffer
экземпляры также являютсяUint8Array
экземплярами », поэтомуbuf.toString()
в этом случае работает.источник
Buffer
также Uint8Array. Спасибо!Buffer.from(uint8array).toString('utf-8')
Решение, данное Альбертом, работает хорошо до тех пор, пока предоставленная функция вызывается нечасто и используется только для массивов небольшого размера, в противном случае это совершенно неэффективно. Вот усовершенствованное решение ванильного JavaScript, которое работает как для Node, так и для браузеров и имеет следующие преимущества:
• Эффективно работает для всех размеров массивов октетов.
• Не создает промежуточных отбрасываемых струн
• Поддерживает 4-байтовые символы на современных движках JS (в противном случае заменяется "?")
источник
Сделайте то, что сказал @Sudhir, а затем, чтобы получить строку из списка чисел, разделенных запятыми, используйте:
Это даст вам нужную строку, если она все еще актуальна
источник
String.fromCharCode.apply(null, unitArr);
. Как уже упоминалось, он не обрабатывает кодировку UTF8, но иногда это бывает достаточно просто, если вам нужна только поддержка ASCII, но нет доступа к TextEncoder / TextDecoder.Если вы не можете использовать API TextDecoder, потому что он не поддерживается в IE :
источник
Попробуйте эти функции,
источник: https://gist.github.com/tomfa/706d10fed78c497731ac , слава Tomfa
источник
Я был разочарован, увидев, что люди не демонстрируют, как идти обоими путями, и не показывают, что все работает с нетривиальными строками UTF8. Я нашел сообщение на codereview.stackexchange.com, в котором есть код, который хорошо работает. Я использовал его, чтобы превратить древние руны в байты, проверить некоторую криптографию на байтах, а затем преобразовать вещи обратно в строку. Рабочий код находится на github здесь . Для наглядности переименовал методы:
Модульный тест использует эту строку UTF-8:
Обратите внимание, что длина строки составляет всего 117 символов, но длина в байтах при кодировании составляет 234 байта.
Если я раскомментирую строки console.log, я вижу, что декодируемая строка - это та же строка, которая была закодирована (с байтами, переданными через алгоритм совместного использования секрета Шамира!):
источник
String.fromCharCode.apply(null, chars)
выдаст ошибку, еслиchars
будет слишком большим.But beware: by using apply this way, you run the risk of exceeding the JavaScript engine's argument length limit. The consequences of applying a function with too many arguments (that is, more than tens of thousands of arguments) varies across engines. (The JavaScriptCore engine has hard-coded argument limit of 65536.
В NodeJS есть буферы, и преобразование строк с их помощью очень просто. Более того, Uint8Array легко преобразовать в буфер. Попробуйте этот код, он работал у меня в Node практически для любого преобразования, связанного с Uint8Arrays:
Мы просто извлекаем ArrayBuffer из Uint8Array и затем конвертируем его в правильный буфер NodeJS. Затем мы конвертируем буфер в строку (вы можете использовать шестнадцатеричную кодировку или кодировку base64, если хотите).
Если мы хотим преобразовать обратно в Uint8Array из строки, мы сделаем следующее:
Имейте в виду, что если вы объявили кодировку, такую как base64, при преобразовании в строку, вам придется использовать,
Buffer.from(str, "base64")
если вы использовали base64, или любую другую кодировку, которую вы использовали.Это не будет работать в браузере без модуля! Буферы NodeJS просто не существуют в браузере, поэтому этот метод не будет работать, если вы не добавите в браузер функциональность буфера. Это на самом деле очень легко сделать , хотя, просто использовать модуль как это , который является малым и быстро!
источник
`
источник
Я использую этот фрагмент Typescript:
Удалите аннотации типов, если вам нужна версия JavaScript. Надеюсь это поможет!
источник