Преобразование между UTF-8 ArrayBuffer и строкой
у меня есть ArrayBuffer
, который содержит строку в кодировке UTF-8 и я не могу найти стандартный способ преобразования такого ArrayBuffer
в JS String
(который, как я понимаю, кодируется с помощью UTF-16).
Я видел этот код во многих местах, но я не вижу, как он будет работать с любыми кодовыми точками UTF-8, которые длиннее 1 байта.
return String.fromCharCode.apply(null, new Uint8Array(data));
аналогично, я не могу найти стандартный способ преобразования String
в кодировке UTF-8 ArrayBuffer
.
8 ответов
function stringToUint(string) {
var string = btoa(unescape(encodeURIComponent(string))),
charList = string.split(''),
uintArray = [];
for (var i = 0; i < charList.length; i++) {
uintArray.push(charList[i].charCodeAt(0));
}
return new Uint8Array(uintArray);
}
function uintToString(uintArray) {
var encodedString = String.fromCharCode.apply(null, uintArray),
decodedString = decodeURIComponent(escape(atob(encodedString)));
return decodedString;
}
Я сделал, с помощью интернета, эти функции, они должны решить ваши проблемы! Вот это рабочая JSFiddle.
редактировать:
поскольку источник Uint8Array является внешним, и вы не можете использовать atob
вам просто нужно снять его(рабочая скрипку):
function uintToString(uintArray) {
var encodedString = String.fromCharCode.apply(null, uintArray),
decodedString = decodeURIComponent(escape(encodedString));
return decodedString;
}
Это должно работать:
// http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt
/* utf.js - UTF-8 <=> UTF-16 convertion
*
* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
* Version: 1.0
* LastModified: Dec 25 1999
* This library is free. You can redistribute it and/or modify it.
*/
function Utf8ArrayToStr(array) {
var out, i, len, c;
var char2, char3;
out = "";
len = array.length;
i = 0;
while (i < len) {
c = array[i++];
switch (c >> 4)
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
out += String.fromCharCode(c);
break;
case 12: case 13:
// 110x xxxx 10xx xxxx
char2 = array[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}
return out;
}
это несколько чище, чем другие решения, потому что он не использует никаких хаков и не зависит от функций браузера JS, например, работает также в других средах JS.
Проверьте демо JSFiddle.
С помощью TextEncoder и TextDecoder
var uint8array = new TextEncoder("utf-8").encode("Plain Text");
var string = new TextDecoder().decode(uint8array);
console.log(uint8array ,string )
есть полифилл для кодирование на Github:кодирование текста. Это легко для узла или браузера, и Readme советует следующее:
var uint8array = TextEncoder(encoding).encode(string);
var string = TextDecoder(encoding).decode(uint8array);
если я правильно помню,'utf-8'
- это encoding
вам нужно, и, конечно, вам нужно обернуть буфер:
var uint8array = new Uint8Array(utf8buffer);
надеюсь, это работает так же хорошо для вас, как и для меня.
Если вы делаете это в браузере, нет встроенных библиотек кодировки символов, но вы можете получить с:
function pad(n) {
return n.length < 2 ? "0" + n : n;
}
var array = new Uint8Array(data);
var str = "";
for( var i = 0, len = array.length; i < len; ++i ) {
str += ( "%" + pad(array[i].toString(16)))
}
str = decodeURIComponent(str);
вот демонстрация, которая декодирует 3-байтовый блок UTF-8:http://jsfiddle.net/Z9pQE/
Я столкнулся с той же проблемой, но должен был иметь возможность анализировать/писать кодированные данные UTF8 постепенно. Вот Либ я просто сделал, чтобы решать этот вопрос https://github.com/nfroidure/UTF8.js .
Edit: кажется, Mozilla готовит что-то для нас: StringView ( https://developer.mozilla.org/en-US/docs/Code_snippets/StringView?redirectlocale=en-US&redirectslug=Web%2FJavaScript%2FTyped_arrays%2FStringView#encoding_values)
основной проблемой программистов, ищущих преобразование из байтового массива в строку, является кодировка (сжатие) символов Юникода UTF-8. Этот код поможет вам:
var getString = function (strBytes) {
var MAX_SIZE = 0x4000;
var codeUnits = [];
var highSurrogate;
var lowSurrogate;
var index = -1;
var result = '';
while (++index < strBytes.length) {
var codePoint = Number(strBytes[index]);
if (codePoint === (codePoint & 0x7F)) {
} else if (0xF0 === (codePoint & 0xF0)) {
codePoint ^= 0xF0;
codePoint = (codePoint << 6) | (strBytes[++index] ^ 0x80);
codePoint = (codePoint << 6) | (strBytes[++index] ^ 0x80);
codePoint = (codePoint << 6) | (strBytes[++index] ^ 0x80);
} else if (0xE0 === (codePoint & 0xE0)) {
codePoint ^= 0xE0;
codePoint = (codePoint << 6) | (strBytes[++index] ^ 0x80);
codePoint = (codePoint << 6) | (strBytes[++index] ^ 0x80);
} else if (0xC0 === (codePoint & 0xC0)) {
codePoint ^= 0xC0;
codePoint = (codePoint << 6) | (strBytes[++index] ^ 0x80);
}
if (!isFinite(codePoint) || codePoint < 0 || codePoint > 0x10FFFF || Math.floor(codePoint) != codePoint)
throw RangeError('Invalid code point: ' + codePoint);
if (codePoint <= 0xFFFF)
codeUnits.push(codePoint);
else {
codePoint -= 0x10000;
highSurrogate = (codePoint >> 10) | 0xD800;
lowSurrogate = (codePoint % 0x400) | 0xDC00;
codeUnits.push(highSurrogate, lowSurrogate);
}
if (index + 1 == strBytes.length || codeUnits.length > MAX_SIZE) {
result += String.fromCharCode.apply(null, codeUnits);
codeUnits.length = 0;
}
}
return result;
}
всего наилучшего !