Wie kann ich einen String in Bytearray mit JavaScript konvertieren? Die Ausgabe sollte dem folgenden C # -Code entsprechen.
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] bytes = encoding.GetBytes(AnyString);
Da UnicodeEncoding standardmäßig UTF-16 mit Little-Endianness ist.
Bearbeiten: Ich muss die vom Bytearray generierte Client-Seite mit der auf der Server-Seite generierten Client-Seite mit dem obigen C # -Code abgleichen.
javascript
shas
quelle
quelle
Antworten:
In C # läuft dies
Erstellt ein Array mit
Für ein Zeichen, dessen Code größer als 255 ist, sieht es so aus
Wenn Sie ein sehr ähnliches Verhalten in JavaScript wünschen, können Sie dies tun (v2 ist eine etwas robustere Lösung, während die Originalversion nur für 0x00 ~ 0xff funktioniert).
quelle
Wenn Sie nach einer Lösung suchen, die in node.js funktioniert, können Sie Folgendes verwenden:
quelle
Ich nehme an, C # und Java erzeugen Arrays mit gleichen Bytes. Wenn Sie Nicht-ASCII-Zeichen haben, reicht es nicht aus, eine zusätzliche 0 hinzuzufügen. Mein Beispiel enthält einige Sonderzeichen:
Ich weiß nicht, ob C # Stückliste (Byte Order Marks) platziert, aber bei Verwendung von UTF-16
String.getBytes
fügt Java die folgenden Bytes hinzu: 254 255.Bearbeiten:
Ein Sonderzeichen (U + 1D11E) wurde hinzugefügt. MUSICAL SYMBOL G CLEF (außerhalb von BPM, also nicht nur 2 Bytes in UTF-16, sondern 4.
Aktuelle JavaScript-Versionen verwenden intern "UCS-2", sodass dieses Symbol 2 normale Zeichen einnimmt.
Ich bin mir nicht sicher, aber wenn
charCodeAt
wir es verwenden, erhalten wir anscheinend genau die Ersatzcodepunkte, die auch in UTF-16 verwendet werden, sodass Nicht-BPM-Zeichen korrekt behandelt werden.Dieses Problem ist absolut nicht trivial. Dies kann von den verwendeten JavaScript-Versionen und Engines abhängen. Wenn Sie also zuverlässige Lösungen wünschen, sollten Sie sich Folgendes ansehen:
quelle
charCodeAt
eine UTF-16-Codeeinheit im Bereich von 0 bis 65535 zurück. Zeichen außerhalb des 2-Byte-Bereichs werden wie in UTF-16 als Ersatzpaare dargestellt. (Übrigens gilt dies für Zeichenfolgen in mehreren anderen Sprachen, einschließlich Java und C #.)(charCode & 0xFF00) >> 8
redundant, müssen Sie es vor dem Verschieben nicht maskieren.Der einfachste Weg im Jahr 2018 sollte TextEncoder sein, aber das zurückgegebene Element ist kein Byte-Array, sondern Uint8Array. (Und nicht alle Browser unterstützen es)
quelle
new TextDecoder().decode(new TextEncoder().encode(str)) == str
.TextEncoder
: caniuseUTF-16-Byte-Array
JavaScript codiert Zeichenfolgen wie die von C # als UTF-16 ,
UnicodeEncoding
sodass die Byte-Arrays genau mit übereinstimmencharCodeAt()
und jedes zurückgegebene Byte-Paar in zwei separate Bytes aufteilen sollten, wie in:Beispielsweise:
Wenn Sie jedoch ein UTF-8-Byte-Array erhalten möchten, müssen Sie die Bytes transkodieren.
UTF-8-Byte-Array
Die Lösung fühlt sich nicht trivial an, aber ich habe den folgenden Code in einer stark frequentierten Produktionsumgebung mit großem Erfolg verwendet ( Originalquelle ).
Für den interessierten Leser habe ich außerdem meine Unicode-Helfer veröffentlicht , die mir helfen, mit Zeichenfolgenlängen zu arbeiten, die von anderen Sprachen wie PHP gemeldet werden.
quelle
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.
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.charCodeAt
Gibt eine maximale Anzahl von 2 Bytes zurück und stimmt genau mit UTF-16 überein. Für UTF-32String.prototype.codePointAt
wird 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 FunktionstringToAsciiByteArray
in 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.
quelle
'02'
sind dort,[ 48, 0, 50, 0 ]
wo IhrestringToUtf16ByteArray
Funktion zurückkehrt[ 0, 48, 0, 50 ]
. Welches ist korrekt?Da ich die Antwort nicht kommentieren kann, würde ich auf Jin Izzraeels Antwort aufbauen
indem Sie sagen, dass Sie dies verwenden könnten, wenn Sie einen Node.js-Puffer in Ihrem Browser verwenden möchten.
https://github.com/feross/buffer
Daher ist der Einwand von Tom Stickel nicht gültig, und die Antwort ist in der Tat eine gültige Antwort.
quelle
quelle
encodeHex
gibt ein Array von 16-Bit-Zahlen zurück, keine Bytes.Die beste Lösung, die ich vor Ort gefunden habe (obwohl höchstwahrscheinlich grob), wäre:
Obwohl ich bemerke, dass diese Frage seit über einem Jahr hier ist.
quelle
charCodeAt
eine 16-Bit-UTF-16-Codeeinheit zurück, sodass Sie keine Logik mit variabler Länge benötigen. Sie können einfach charCodeAt aufrufen, das Ergebnis in zwei 8-Bit-Bytes aufteilen und diese in das Ausgabearray einfügen (Byte niedrigster Ordnung zuerst, da die Frage nach UTF-16LE fragt).Ich weiß, dass die Frage fast 4 Jahre alt ist, aber das hat bei mir reibungslos funktioniert:
Wenn Sie nur mit Zeichenfolgen und ohne Array arbeiten möchten, können Sie Folgendes verwenden:
quelle
bytes
Array enthält keine 'Bytes', sondern 16-Bit-Zahlen, die die Zeichenfolge in UTF-16-Codeeinheiten darstellen. Dies ist fast das, wonach die Frage gestellt wurde, aber eigentlich nur durch Zufall.Hier ist dieselbe Funktion, die @BrunoLM veröffentlicht hat und die in eine String-Prototypfunktion konvertiert wurde:
Wenn Sie die Funktion als solche definieren, können Sie die Methode .getBytes () für eine beliebige Zeichenfolge aufrufen:
quelle
Sie brauchen keinen Unterstrich, verwenden Sie einfach die integrierte Karte:
quelle