Zainspirowany odpowiedzią @ hgoebl. Jego kod jest dla UTF-16 i potrzebowałem czegoś dla US-ASCII. Oto bardziej kompletna odpowiedź obejmująca US-ASCII, UTF-16 i 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 ma zmienną długość i nie jest uwzględniany, ponieważ musiałbym sam napisać kodowanie. UTF-8 i UTF-16 mają zmienną długość. UTF-8, UTF-16 i UTF-32 mają minimalną liczbę bitów, jak wskazuje ich nazwa. Jeśli znak UTF-32 ma punkt kodowy 65, oznacza to, że istnieją 3 wiodące 0. Ale ten sam kod dla UTF-16 ma tylko 1 wiodące 0. Z drugiej strony US-ASCII ma stałą szerokość 8-bitową, co oznacza, że można go bezpośrednio przetłumaczyć na bajty.
String.prototype.charCodeAtzwraca maksymalną liczbę 2 bajtów i dokładnie dopasowuje kod UTF-16. Jednak dla UTF-32 String.prototype.codePointAtjest potrzebny, który jest częścią propozycji ECMAScript 6 (Harmony). Ponieważ charCodeAt zwraca 2 bajty, czyli więcej możliwych znaków niż może reprezentować US-ASCII, funkcja stringToAsciiByteArrayzwróci w takich przypadkach zamiast podzielić znak na pół i zabrać jeden lub oba bajty.
Zwróć uwagę, że ta odpowiedź jest nietrywialna, ponieważ kodowanie znaków jest nietrywialne. Rodzaj tablicy bajtów zależy od kodowania znaków, które mają reprezentować te bajty.
javascript ma opcję wewnętrznego używania UTF-16 lub UCS-2, ale ponieważ ma metody, które działają jak UTF-16, nie rozumiem, dlaczego jakakolwiek przeglądarka miałaby używać UCS-2. Zobacz także: https://mathiasbynens.be/notes/javascript-encoding
Tak, wiem, że to pytanie ma 4 lata, ale potrzebowałem tej odpowiedzi dla siebie.