Inspiriert von @ hgoebls Antwort. Sein Code ist für UTF-16 und ich brauchte etwas für US-ASCII. Hier ist eine vollständigere Antwort zu US-ASCII, UTF-16 und UTF-32.
/**@returns {Array} bytes of US-ASCII*/
function stringToAsciiByteArray(str)
{
var bytes = [];
for (var i = 0; i < str.length; ++i)
{
var charCode = str.charCodeAt(i);
if (charCode > 0xFF) // char > 1 byte since charCodeAt returns the UTF-16 value
{
throw new Error('Character ' + String.fromCharCode(charCode) + ' can\'t be represented by a US-ASCII byte.');
}
bytes.push(charCode);
}
return bytes;
}
/**@returns {Array} bytes of UTF-16 Big Endian without BOM*/
function stringToUtf16ByteArray(str)
{
var bytes = [];
//currently the function returns without BOM. Uncomment the next line to change that.
//bytes.push(254, 255); //Big Endian Byte Order Marks
for (var i = 0; i < str.length; ++i)
{
var charCode = str.charCodeAt(i);
//char > 2 bytes is impossible since charCodeAt can only return 2 bytes
bytes.push((charCode & 0xFF00) >>> 8); //high byte (might be 0)
bytes.push(charCode & 0xFF); //low byte
}
return bytes;
}
/**@returns {Array} bytes of UTF-32 Big Endian without BOM*/
function stringToUtf32ByteArray(str)
{
var bytes = [];
//currently the function returns without BOM. Uncomment the next line to change that.
//bytes.push(0, 0, 254, 255); //Big Endian Byte Order Marks
for (var i = 0; i < str.length; i+=2)
{
var charPoint = str.codePointAt(i);
//char > 4 bytes is impossible since codePointAt can only return 4 bytes
bytes.push((charPoint & 0xFF000000) >>> 24);
bytes.push((charPoint & 0xFF0000) >>> 16);
bytes.push((charPoint & 0xFF00) >>> 8);
bytes.push(charPoint & 0xFF);
}
return bytes;
}
UTF-8 hat eine variable Länge und ist nicht enthalten, da ich die Codierung selbst schreiben müsste. UTF-8 und UTF-16 sind variabel lang. UTF-8, UTF-16 und UTF-32 haben eine Mindestanzahl von Bits, wie der Name schon sagt. Wenn ein UTF-32-Zeichen einen Codepunkt von 65 hat, bedeutet dies, dass es 3 führende Nullen gibt. Der gleiche Code für UTF-16 hat jedoch nur 1 führende 0. US-ASCII hingegen hat eine feste Breite von 8 Bit, was bedeutet, dass es direkt in Bytes übersetzt werden kann.
String.prototype.charCodeAtGibt eine maximale Anzahl von 2 Bytes zurück und stimmt genau mit UTF-16 überein. Für UTF-32 String.prototype.codePointAtwird jedoch benötigt, was Teil des ECMAScript 6 (Harmony) -Vorschlags ist. Da charCodeAt 2 Bytes zurückgibt, was mehr mögliche Zeichen sind, als US-ASCII darstellen kann, wird die Funktion stringToAsciiByteArrayin solchen Fällen ausgelöst, anstatt das Zeichen in zwei Hälften zu teilen und eines oder beide Bytes zu verwenden.
Beachten Sie, dass diese Antwort nicht trivial ist, da die Zeichenkodierung nicht trivial ist. Welche Art von Byte-Array Sie möchten, hängt davon ab, welche Zeichencodierung diese Bytes darstellen sollen.
Javascript hat die Möglichkeit, entweder UTF-16 oder UCS-2 intern zu verwenden. Da es jedoch Methoden gibt, die sich wie UTF-16 verhalten, verstehe ich nicht, warum ein Browser UCS-2 verwenden würde. Siehe auch: https://mathiasbynens.be/notes/javascript-encoding
Ja, ich weiß, dass die Frage 4 Jahre alt ist, aber ich brauchte diese Antwort für mich.