ArrayBuffer a base64 cadena

Necesito un eficiente (leer nativo) para convertir un ArrayBuffer a una cadena base64 que debe utilizarse en un multipart post.

InformationsquelleAutor zaheer | 2012-02-13

10 Kommentare

  1. 186
    function _arrayBufferToBase64( buffer ) {
        var binary = '';
        var bytes = new Uint8Array( buffer );
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode( bytes[ i ] );
        }
        return window.btoa( binary );
    }

    pero no nativas implementaciones son más rápidos, por ejemplo, https://gist.github.com/958841
    ver http://jsperf.com/encoding-xhr-image-data/6

    • He probado el no-nativo de la aplicación desde el enlace y se tomó 1 minuto y medio para convertir un 1M tamaño de búfer mientras que el código del bucle anterior sólo tomó 1sec.
    • Me gusta la sencillez de este método, pero todos los que la concatenación de cadenas puede ser costoso. Se ve como la construcción de una matriz de los personajes y join()ing al final es significativamente más rápido en Firefox, IE y Safari (pero bastante más lento en Chrome): jsperf.com/tobase64-implementations
    • Yo estoy usando esta función para la matriz de amortiguamiento en base64 de la conversión, pero no soy capaz de volver a la matriz de amortiguamiento. He wrriten un _base64ToArrayBuffer() función aquí: código compartido.io/PT4pb, pero que me da un error como: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.
    • esto no es trabajado este JSZip. yo busque otra forma de github.com/michael/github/issues/137
    • Trabajó para mí :). Gracias!.
    • He comprobado que este produce la salida derecha.
    • Estoy tratando de 50 mb archivo pdf cargar con angualrjs y webapi2. Estoy usando por encima de la línea de código , después de subir el archivo, la página recibió estrelló y ahorcado . Debajo de la línea de código ,que yo estaba acostumbrado, pero conseguir que el valor null en webapi método. «var base64String = btoa(Cadena.fromCharCode.aplicar(null, new Uint8Array(arrayBuffer)));» por favor, sugerir cualquier idea …
    • Esto no es binario seguro. ¿Alguien sabe acerca de un binario opción segura?
    • la última versión de: jsperf.com/encoding-xhr-image-data/55
    • No seguro. Ver a @chemoish respuesta
    • Lamentablemente no trabajo en node.js. Porque de node.js’ Utf-8 codificación de cadena String.fromCharCode() se comportan diferente para los valores de byte >= 0x80.

  2. 80

    Esto funciona muy bien para mí:

    var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(arrayBuffer)));

    En ES6, la sintaxis es un poco más simple:

    let base64String = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));

    Como se señaló en los comentarios, este método puede resultar en un error de tiempo de ejecución en algunos de los navegadores cuando el ArrayBuffer es grande. El tamaño exacto límite depende de la implementación en cualquier caso.

    • Me gusta este método mejor para la concisión, pero conseguir un «máximo de la pila de llamadas tamaño excedido error». El bucle de la técnica anterior se presenta en torno a eso.
    • También estoy recibiendo un tamaño de pila de error, así que he usado mobz la respuesta y funcionó muy bien.
    • Esto funciona de manera concisa, gracias
    • No trabajo para grandes buffers. Una ligera modificación para que funcione: btoa([].reduce.call(new Uint8Array(bufferArray),function(p,c){return p+String.fromCharCode(c)},''))
    • Estoy tratando de 50 mb archivo pdf cargar con angualrjs y webapi2. Estoy usando por encima de la línea de código , después de subir el archivo, la página recibió estrelló y ahorcado . Debajo de la línea de código ,que yo estaba acostumbrado, pero conseguir que el valor null en webapi método. «var base64String = btoa(Cadena.fromCharCode.aplicar(null, new Uint8Array(arrayBuffer)));» por favor, sugerir cualquier idea …
    • puede agregar el último marcado/cadena de imagen a su respuesta así por casualidad? Tengo imágenes BMP almacenadas en SQL que estoy tratando de mostrar, pero este código no funciona: ‘data:image/bmp;base64,’ + btoa(Cadena.fromCharCode.aplicar(null, new Uint8Array(arrayBuffer)));
    • No veo qué hay de malo con esa expresión. Consulte aquí por su pregunta. Si esto no ayuda, entonces usted debe hacer una nueva pregunta y proporcionar algo más de información.
    • No seguro. Ver a @chemoish respuesta
    • es seguro para los caracteres en el código rango de 0-255, como es aquí el caso (a Pensar sobre las 8 en Uint8Array).

  3. 31

    Hay otra manera asincrónica uso de Blob y FileReader.

    Yo no prueba el rendimiento. Pero es una forma diferente de pensar.

    function arrayBufferToBase64( buffer, callback ) {
        var blob = new Blob([buffer],{type:'application/octet-binary'});
        var reader = new FileReader();
        reader.onload = function(evt){
            var dataurl = evt.target.result;
            callback(dataurl.substr(dataurl.indexOf(',')+1));
        };
        reader.readAsDataURL(blob);
    }
    
    //example:
    var buf = new Uint8Array([11,22,33]);
    arrayBufferToBase64(buf, console.log.bind(console)); //"CxYh"
    • algunos de optimización: en lugar de ‘evt.destino «puede usar «lector»
    • Uso dataurl.split(',', 2)[1]en lugar de dataurl.substr(dataurl.indexOf(',')+1).
    • Esto no parece ser garantizado para trabajar. De acuerdo a la w3c.github.io/FileAPI/#tema-f80bda5b readAsDataURL, en teoría, podría devolver un porcentaje codificado dataURI (Y parece ser que es en realidad el caso en jsdom)
    • ¿Por qué split ser mejor que substring?
    • split es más corto. pero dataurl puede contener una o más comas(,), split no es seguro.
  4. 30

    Para aquellos que les gusta resumen, el otro, el uso de Array.reduce que no va a provocar el desbordamiento de pila:

    var base64 = btoa(
      new Uint8Array(arrayBuffer)
        .reduce((data, byte) => data + String.fromCharCode(byte), '')
    );
    • No estoy seguro si eso es realmente sexy. Después de todo, usted está creando <amount of Bytes in the buffer> nuevas cadenas.
    • ¿btoa(new Uint8Array(arraybuffer).reduce((data,byte)=>(data.push(String.fromCharCode(byte)),data),[]).join(''))?
  5. 12

    He utilizado este y funciona para mí.

    function arrayBufferToBase64( buffer ) {
        var binary = '';
        var bytes = new Uint8Array( buffer );
        var len = bytes.byteLength;
        for (var i = 0; i < len; i++) {
            binary += String.fromCharCode( bytes[ i ] );
        }
        return window.btoa( binary );
    }
    
    
    
    function base64ToArrayBuffer(base64) {
        var binary_string =  window.atob(base64);
        var len = binary_string.length;
        var bytes = new Uint8Array( len );
        for (var i = 0; i < len; i++)        {
            bytes[i] = binary_string.charCodeAt(i);
        }
        return bytes.buffer;
    }
    • No seguro. Ver a @chemoish respuesta
  6. 10

    Mi recomendación es NO utilizar los btoa estrategias—como no codificar correctamente todos los ArrayBuffer‘s…

    reescribir el DOMs atob() y btoa()

    Desde DOMStrings son de 16 bits codificados en cadenas, en la mayoría de los navegadores de llamadas de la ventana.btoa en una cadena Unicode causará un Personaje Fuera De Rango excepción si un personaje supera el rango de 8-bits en ASCII carácter codificado.

    Aunque nunca me he encontrado con este error exacto, he encontrado que muchos de los ArrayBuffer‘s he intentado codificar han codificado de forma incorrecta.

    Me gustaría utilizar MDN recomendación o gist.

    • btoa no funciona en Cadena, pero el OP está pidiendo ArrayBuffer.
    • Mucho de esto, así que muchos de los fragmentos de aquí que recomendar algo malo! He visto este error varias veces, donde las personas ciegas uso atob y btoa.
    • Todos los de la matriz de búferes debe ser codificado de bellas uso de las estrategias en otras respuestas, atob/btoa es un problema sólo de texto que contiene caracteres mayor que 0xFF (que las matrices de bytes, por definición, no). El MDN advertencia no se aplica debido a que cuando se utiliza la estrategia en las otras respuestas, usted está garantizado para tener una cadena que sólo se compone de caracteres ASCII como cualquier valor de un Uint8Array está garantizado para estar entre 0 y 255 que significa Cadena.fromCharCode está garantizado el retorno de un personaje que no está fuera de rango.
  7. 6

    A continuación son 2 simples funciones para la conversión de Uint8Array a Cadena Base64 y de nuevo

    arrayToBase64String(a) {
        return btoa(String.fromCharCode(...a));
    }
    
    base64StringToArray(s) {
        let asciiString = atob(s);
        return new Uint8Array([...asciiString].map(char => char.charCodeAt(0)));
    }
    • Este es un confuso respuesta. Que no se parece en aspecto válido de JavaScript y es un Uint8Array ArrayBuffer?
    • Agregar el function palabra clave y se debe trabajar en un navegador moderno.
    • Impresionante! btoa(Cadena.fromCharCode(…a)); es más corta versión que he visto hasta ahora para codificar Uint8Array.
  8. 1

    Se puede derivar una matriz normal de la ArrayBuffer mediante Array.prototype.slice.
    El uso de una función como Array.prototype.map para convertir los bytes en caracteres y join junto a forma de cadena.

    function arrayBufferToBase64(ab){
    
        var dView = new Uint8Array(ab);   //Get a byte view        
    
        var arr = Array.prototype.slice.call(dView); //Create a normal array        
    
        var arr1 = arr.map(function(item){        
          return String.fromCharCode(item);    //Convert
        });
    
        return window.btoa(arr1.join(''));   //Form a string
    
    }

    Este método es más rápido ya que no hay concatenaciones de cadenas que se ejecutan en él.

    • No seguro. Ver a @chemoish respuesta
  9. -2

    Por mi lado, a través de Chrome navegador, he tenido que utilizar DataView() para leer un arrayBuffer

    function _arrayBufferToBase64( tabU8A ) {
    var binary = '';
    let lecteur_de_donnees = new DataView(tabU8A);
    var len = lecteur_de_donnees.byteLength;
    var chaine = '';
    var pos1;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode( lecteur_de_donnees.getUint8( i ) );
    }
    chaine = window.btoa( binary )
    return chaine;}
  10. -3
    function _arrayBufferToBase64(uarr) {
        var strings = [], chunksize = 0xffff;
        var len = uarr.length;
    
        for (var i = 0; i * chunksize < len; i++){
            strings.push(String.fromCharCode.apply(null, uarr.subarray(i * chunksize, (i + 1) * chunksize)));
        }
    
        return strings.join("");
    }

    Esto es mejor, si el uso de JSZip para descomprima el archivo de cadena de

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea