Вдохновленный ответом @hgoebl. Его код предназначен для UTF-16, а мне нужно что-то для US-ASCII. Итак, вот более полный ответ, охватывающий US-ASCII, UTF-16 и UTF-32.
function stringToAsciiByteArray(str)
{
var bytes = [];
for (var i = 0; i < str.length; ++i)
{
var charCode = str.charCodeAt(i);
if (charCode > 0xFF)
{
throw new Error('Character ' + String.fromCharCode(charCode) + ' can\'t be represented by a US-ASCII byte.');
}
bytes.push(charCode);
}
return bytes;
}
function stringToUtf16ByteArray(str)
{
var bytes = [];
for (var i = 0; i < str.length; ++i)
{
var charCode = str.charCodeAt(i);
bytes.push((charCode & 0xFF00) >>> 8);
bytes.push(charCode & 0xFF);
}
return bytes;
}
function stringToUtf32ByteArray(str)
{
var bytes = [];
for (var i = 0; i < str.length; i+=2)
{
var charPoint = str.codePointAt(i);
bytes.push((charPoint & 0xFF000000) >>> 24);
bytes.push((charPoint & 0xFF0000) >>> 16);
bytes.push((charPoint & 0xFF00) >>> 8);
bytes.push(charPoint & 0xFF);
}
return bytes;
}
UTF-8 имеет переменную длину и не включен, потому что мне пришлось бы писать кодировку самостоятельно. UTF-8 и UTF-16 имеют переменную длину. UTF-8, UTF-16 и UTF-32 имеют минимальное количество бит, как указывает их название. Если символ UTF-32 имеет кодовую точку 65, это означает, что есть 3 ведущих нуля. Но тот же код для UTF-16 имеет только 1 ведущий 0. US-ASCII, с другой стороны, имеет фиксированную ширину 8 бит, что означает, что он может быть напрямую преобразован в байты.
String.prototype.charCodeAtвозвращает максимальное количество 2 байта и точно соответствует UTF-16. Однако String.prototype.codePointAtтребуется UTF-32, который является частью предложения ECMAScript 6 (Harmony). Поскольку charCodeAt возвращает 2 байта, что является большим количеством возможных символов, чем может представить US-ASCII, функция stringToAsciiByteArrayв таких случаях выбрасывает вместо разделения символа пополам и получения одного или обоих байтов.
Обратите внимание, что этот ответ нетривиален, потому что кодировка символов нетривиальна. Какой тип массива байтов вам нужен, зависит от того, какую кодировку символов вы хотите представлять в этих байтах.
javascript имеет возможность внутреннего использования либо UTF-16, либо UCS-2, но поскольку у него есть методы, которые действуют так, как будто это UTF-16, я не понимаю, почему какой-либо браузер будет использовать UCS-2. См. Также: https://mathiasbynens.be/notes/javascript-encoding
Да, я знаю, что этому вопросу 4 года, но мне нужен был этот ответ для себя.