¿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 para que las funciones funcionen al revés?
Gracias.
Shao
javascript
casting
user385579
fuente
fuente
Respuestas:
Necesita analizar cada octeto hasta el número y usar ese valor para obtener un carácter, 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
se puede escribir 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 blobs 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
fuente
String.fromCharCode.apply(String, array)
no es seguro para cadenas muy largas en Safari. Hay un problema en JavaScriptCore que significa que las funciones no pueden tomar más de 65536 argumentos, o se lanzará un RangeError. También bloquea el navegador en matrices un poco más pequeñas que eso. Ver bugs.webkit.org/show_bug.cgi?id=80797bin2String([0xE2, 0x98, 0xB9])
Simplemente
apply
su matriz de bytes aString.fromCharCode
. Por ejemploString.fromCharCode.apply(null, [102, 111, 111])
es igual a 'foo'.Advertencia: funciona para matrices de menos de 65535. Documentos de MDN aquí .
fuente
Pruebe la nueva API de codificación de texto:
// create an array view of some valid bytes let bytesView = new Uint8Array([104, 101, 108, 108, 111]); console.log(bytesView); // convert bytes to string // encoding can be specfied, defaults to utf-8 which is ascii. let str = new TextDecoder().decode(bytesView); console.log(str); // convert string to bytes // encoding can be specfied, defaults to utf-8 which is ascii. let bytes2 = new TextEncoder().encode(str); // look, they're the same! console.log(bytes2); console.log(bytesView);
fuente
Esto debería funcionar:
String.fromCharCode(...array);
O
String.fromCodePoint(...array)
fuente
Ese string2Bin se puede escribir de manera aún más sucinta y sin bucles, ¡para empezar!
function string2Bin ( str ) { return str.split("").map( function( val ) { return val.charCodeAt( 0 ); } ); }
fuente
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(''); }
fuente
Incluso si llego un poco tarde, pensé que sería interesante para los futuros usuarios compartir algunas implementaciones de una sola línea que hice con ES6.
Una cosa que considero importante dependiendo de su entorno y / y lo que hará con los datos es preservar el valor de byte completo. Por ejemplo,
(5).toString(2)
le dará101
, pero la conversión binaria completa es en realidad00000101
, y es por eso que es posible que deba crear unaleftPad
implementación para completar el byte de cadena con ceros a la izquierda. Pero es posible que no lo necesite en absoluto, como demostraron otras respuestas.Si ejecuta el siguiente fragmento de código, verá que la primera salida es la conversión de la
abc
cadena en una matriz de bytes y, justo después, la 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))
fuente
Cadena a matriz de bytes:
"FooBar".split('').map(c => c.charCodeAt(0));
Matriz de bytes a cadena:
[102, 111, 111, 98, 97, 114].map(c => String.fromCharCode(c)).join('');
fuente
Demasiado tarde para responder, pero si su entrada está en forma de bytes ASCII, entonces puede probar esta solución:
function convertArrToString(rArr){ //Step 1: Convert each element to character let tmpArr = new Array(); rArr.forEach(function(element,index){ tmpArr.push(String.fromCharCode(element)); }); //Step 2: Return the string by joining the elements return(tmpArr.join("")); } function convertArrToHexNumber(rArr){ return(parseInt(convertArrToString(rArr),16)); }
fuente
Si está utilizando node.js , puede hacer esto:
yourByteArray.toString('base64');
fuente
No encontré ninguna solución que funcionara con caracteres UTF-8.
String.fromCharCode
es bueno hasta que encuentre el carácter de 2 bytes.Por ejemplo, Hüser vendrá como
[0x44,0x61,0x6e,0x69,0x65,0x6c,0x61,0x20,0x48,0xc3,0xbc,0x73,0x65,0x72]
Pero si lo revisa,
String.fromCharCode
tendrá Hüser, ya que cada byte se convertirá en un carácter por separado.Solución
Actualmente estoy usando la siguiente solución:
function pad(n) { return (n.length < 2 ? '0' + n : n); } function decodeUtf8(data) { return decodeURIComponent( data.map(byte => ('%' + pad(byte.toString(16)))).join('') ); }
fuente
Tenía algunas matrices de bytes descifradas con caracteres de relleno y otras cosas que no necesitaba, así que hice esto (probablemente no sea perfecto, pero funciona para mi uso limitado)
var junk = String.fromCharCode.apply(null, res).split('').map(char => char.charCodeAt(0) <= 127 && char.charCodeAt(0) >= 32 ? char : '').join('');
fuente
Si su matriz está codificada en UTF-8 y no puede usar la API TextDecoder porque no es compatible con IE :
function utf8ArrayToString(aBytes) { var sView = ""; for (var nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) { nPart = aBytes[nIdx]; sView += String.fromCharCode( nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */ /* (nPart - 252 << 30) may be not so safe in ECMAScript! So...: */ (nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */ (nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */ (nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */ (nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128 : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */ (nPart - 192 << 6) + aBytes[++nIdx] - 128 : /* nPart < 127 ? */ /* one byte */ nPart ); } return sView; } let str = utf8ArrayToString([50,72,226,130,130,32,43,32,79,226,130,130,32,226,135,140,32,50,72,226,130,130,79]); // Must show 2H₂ + O₂ ⇌ 2H₂O console.log(str);
fuente
La solución más simple que he encontrado es:
var text = atob(byteArray);
fuente