separado - Conversión de matriz de bytes a cadena en JavaScript
slice javascript (5)
¡Ese string2Bin se puede escribir de forma aún más sucinta y sin bucles para arrancar!
function string2Bin ( str ) {
return str.split("").map( function( val ) {
return val.charCodeAt( 0 );
} );
}
¿Cómo convierto una matriz de bytes en una cadena?
He encontrado estas funciones que hacen lo contrario:
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 hago que las funciones funcionen de otra manera?
Gracias.
Shao
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('''');
}
Incluso si llego un poco tarde, pensé que sería interesante para los futuros usuarios compartir algunas implementaciones one-liners que hice con ES6.
Una cosa que considero importante dependiendo de su entorno o de qué va a hacer con los datos es preservar el valor de bytes completo. Por ejemplo, (5).toString(2)
le dará 101
, pero la conversión binaria completa es en realidad 00000101
, y es por eso que tal vez necesite crear una implementación de 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 el primer resultado es la conversión de la cadena abc
a una matriz de bytes y, a continuación, la re-transformación de dicha matriz en 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))
Necesitas analizar cada octeto de vuelta al número y usar ese 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 string2Bin
actual puede escribirse 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 observar la documentación que vinculó, creo que el método setBytesParameter
espera que la matriz blob contenga los números decimales, no una cadena de bits , 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
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 .