2010-07-07 16 views
45

¿Cómo se convierte una matriz de bytes en una cadena?conversión de matriz de bytes en cadena en javascript

he encontrado estas funciones que hacen a la inversa:

function string2Bin(s) { 
    var b = new Array(); 
    var last = s.length; 

    for (var i = 0; i < last; i++) { 
     var d = s.charCodeAt(i); 
     if (d < 128) 
      b[i] = dec2Bin(d); 
     else { 
      var c = s.charAt(i); 
      alert(c + ' is NOT an ASCII character'); 
      b[i] = -1; 
     } 
    } 
    return b; 
} 

function dec2Bin(d) { 
    var b = ''; 

    for (var i = 0; i < 8; i++) { 
     b = (d%2) + b; 
     d = Math.floor(d/2); 
    } 

    return b; 
} 

Pero ¿Cómo consigo las funciones de trabajo hacia otro lado?

Gracias.

Shao

+0

¿Quieres convertir una matriz de bytes en una cadena, o un conjunto de bits en una cadena? – mcandre

Respuesta

53

Es necesario analizar cada octeto de nuevo a número, y utilizar este valor para obtener un personaje, algo como esto:

function bin2String(array) { 
    var result = ""; 
    for (var i = 0; i < array.length; i++) { 
    result += String.fromCharCode(parseInt(array[i], 2)); 
    } 
    return result; 
} 

bin2String(["01100110", "01101111", "01101111"]); // "foo" 

// Using your string2Bin function to test: 
bin2String(string2Bin("hello world")) === "hello world"; 

Editar: Sí, su actual string2Bin puede haber escrito más brevemente:

function string2Bin(str) { 
    var result = []; 
    for (var i = 0; i < str.length; i++) { 
    result.push(str.charCodeAt(i).toString(2)); 
    } 
    return result; 
} 

Pero al mirar la documentación que vinculó, creo que el setBytesParameter método espera que la matriz de burbuja contiene los números decimales, no es una cadena poco, por lo que podría escribir algo como esto:

function string2Bin(str) { 
    var result = []; 
    for (var i = 0; i < str.length; i++) { 
    result.push(str.charCodeAt(i)); 
    } 
    return result; 
} 

function bin2String(array) { 
    return String.fromCharCode.apply(String, array); 
} 

string2Bin('foo'); // [102, 111, 111] 
bin2String(string2Bin('foo')) === 'foo'; // true 
+0

Gracias por la respuesta súper rápida. Un par de preguntas ... 1) Su función bin2String es impresionante, solo 5 líneas de código. ¿Se puede cambiar la función string2bin para utilizar más funciones de Javascript para acortar la función y la subfunción? ..... – user385579

+1

2) La razón por la que necesito estas conversiones es porque estoy capturando una firma y tengo que convertirla para rellenar un campo BLOB en la base de datos. El problema es que, aunque estas 2 funciones funcionan, algo más va mal. Lo principal es que cuando recupero un BLOB de la base de datos entra en un objeto de matriz de bytes. Sin embargo, cuando estoy escribiendo el BLOB en la base de datos después de ejecutarlo a través de la función original, no es un objeto de matriz de bytes. Esto podría ser lo que está causando el problema. ¿Algunas ideas? – user385579

+0

http://dcx.sybase.com/index.html#1101en/ulmbus_en11/ag-apiref-setbytesparameter.html Esta es la sintaxis que uso para establecer los datos. – user385579

7

Eso string2Bin se puede escribir incluso más de manera sucinta, y sin ningún tipo de bucles, ¡arrancar!

function string2Bin (str) { 
    return str.split("").map(function(val) { 
     return val.charCodeAt(0); 
    }); 
} 
+1

Sería curioso ver si se agregaba las llamadas de función reducen la velocidad. – jocull

+24

Todavía tiene un bucle, simplemente está oculto dentro del mapa(). –

3

creo que esto sería más eficiente:

function toBinString (arr) { 
    var uarr = new Uint8Array(arr.map(function(x){return parseInt(x,2)})); 
    var strings = [], chunksize = 0xffff; 
    // There is a maximum stack size. We cannot call String.fromCharCode with as many arguments as we want 
    for (var i=0; i*chunksize < uarr.length; i++){ 
     strings.push(String.fromCharCode.apply(null, uarr.subarray(i*chunksize, (i+1)*chunksize))); 
    } 
    return strings.join(''); 
} 
19

Simplemente apply su matriz de bytes a String.fromCharCode. Por ejemplo

String.fromCharCode.apply(null, [102, 111, 111]) es igual a 'foo'.

Advertencia: funciona para matrices más cortas que 65535. MDN docs here.

+0

Esto ya ha sido demostrado por la respuesta aceptada hace 6 años. –

+1

aah, de hecho, me perdí esa línea. Básicamente, estaba buscando un corto de una línea y descarté esa respuesta larga y editada (tal vez demasiado apresurada). –

+0

Oh, eso tiene sentido :) –

1

Incluso si estoy un poco tarde, pensé que sería interesante para los futuros usuarios compartir algunas implementaciones de una sola línea que hice usando ES6.

Una cosa que considero importante en función del entorno y/o qué va a hacer con la información es preservar el valor de byte completo. Por ejemplo, (5).toString(2) le dará 101, pero la conversión binario completo es en realidad 00000101, y por eso puede que tenga que crear una aplicación leftPad para llenar el byte de cadena con ceros a la izquierda. Pero es posible que no lo necesite en absoluto, como otras respuestas demostradas.

Si ejecuta el siguiente fragmento de código, verá que la primera salida es la conversión de la cadena abc a una matriz de bytes y justo después de esa transformación de dicha matriz a su cadena correspondiente.

// For each byte in our array, retrieve the char code value of the binary value 
 
const binArrayToString = array => array.map(byte => String.fromCharCode(parseInt(byte, 2))).join('') 
 

 
// Basic left pad implementation to ensure string is on 8 bits 
 
const leftPad = str => str.length < 8 ? (Array(8).join('0') + str).slice(-8) : str 
 

 
// For each char of the string, get the int code and convert it to binary. Ensure 8 bits. 
 
const stringToBinArray = str => str.split('').map(c => leftPad(c.charCodeAt().toString(2))) 
 

 
const array = stringToBinArray('abc') 
 

 
console.log(array) 
 
console.log(binArrayToString(array))

Cuestiones relacionadas