javascript - Come convertire una stringa in Bytearray




5 Answers

Se stai cercando una soluzione che funzioni in node.js, puoi usare questo:

var myBuffer = [];
var str = 'Stack Overflow';
var buffer = new Buffer(str, 'utf16le');
for (var i = 0; i < buffer.length; i++) {
    myBuffer.push(buffer[i]);
}

console.log(myBuffer);
javascript

Come posso convertire una stringa in bytearray usando JavaScript. L'output dovrebbe essere equivalente al seguente codice C #.

UnicodeEncoding encoding = new UnicodeEncoding();
byte[] bytes = encoding.GetBytes(AnyString);

Poiché UnicodeEncoding è per impostazione predefinita UTF-16 con Little-Endianness.

Modifica: ho il requisito di abbinare il lato client generato da bytearray con quello generato sul lato server usando il codice C # sopra.




Ispirato alla risposta di @ hgoebl. Il suo codice è per UTF-16 e avevo bisogno di qualcosa per US-ASCII. Quindi ecco una risposta più completa che copre US-ASCII, UTF-16 e UTF-32.

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;
}
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;
}
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 è di lunghezza variabile e non è incluso perché dovrei scrivere la codifica da solo. UTF-8 e UTF-16 sono di lunghezza variabile. UTF-8, UTF-16 e UTF-32 hanno un numero minimo di bit come indica il loro nome. Se un carattere UTF-32 ha un punto di codice 65, significa che ci sono 3 0 iniziali. Ma lo stesso codice per UTF-16 ha solo 1 primo 0. US-ASCII d'altra parte ha una larghezza fissa di 8 bit, il che significa che può essere tradotto direttamente in byte.

String.prototype.charCodeAt restituisce un numero massimo di 2 byte e corrisponde esattamente a UTF-16. Tuttavia per UTF-32 è necessario String.prototype.codePointAt che fa parte della proposta ECMAScript 6 (Harmony). Poiché charCodeAt restituisce 2 byte che sono i caratteri più possibili di quelli che US-ASCII può rappresentare, la funzione stringToAsciiByteArray verrà stringToAsciiByteArray in questi casi invece di dividere il carattere a metà e prendere uno o entrambi i byte.

Si noti che questa risposta non è banale in quanto la codifica dei caratteri non è banale. Che tipo di array di byte si desidera dipende dalla codifica dei caratteri che si desidera che quei byte rappresentino.

javascript ha l'opzione di utilizzare internamente UTF-16 o UCS-2 ma dal momento che ha metodi che si comportano come se fosse UTF-16 non vedo perché qualsiasi browser userebbe UCS-2. Vedi anche: https://mathiasbynens.be/notes/javascript-encoding

Sì, lo so che la domanda è di 4 anni ma avevo bisogno di questa risposta per me stesso.




Ecco la stessa funzione che @BrunoLM ha pubblicato convertito in una funzione prototipo di stringa:

String.prototype.getBytes = function () {
  var bytes = [];
  for (var i = 0; i < this.length; ++i) {
    bytes.push(this.charCodeAt(i));
  }
  return bytes;
};

Se si definisce la funzione come tale, è possibile chiamare il metodo .getBytes () su qualsiasi stringa:

var str = "Hello World!";
var bytes = str.getBytes();



La soluzione migliore che ho trovato sul posto (anche se molto probabilmente grezzo) sarebbe:

String.prototype.getBytes = function() {
    var bytes = [];
    for (var i = 0; i < this.length; i++) {
        var charCode = this.charCodeAt(i);
        var cLen = Math.ceil(Math.log(charCode)/Math.log(256));
        for (var j = 0; j < cLen; j++) {
            bytes.push((charCode << (j*8)) & 0xFF);
        }
    }
    return bytes;
}

Anche se noto che questa domanda è qui da più di un anno.




Il modo più semplice nel 2018 dovrebbe essere TextEncoder ma l'elemento restituito non è array di byte, è Uint8Array. (E non tutti i browser lo supportano)

let utf8Decode = new TextDecoder('utf-8');
utf8Encode.encode("eee")
> Uint8Array [ 101, 101, 101 ]



Related


Tags

javascript