Comment convertir un tableau d'octets en chaîne?
J'ai trouvé ces fonctions qui font l'inverse:
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;
}
Mais comment faire fonctionner les fonctions dans l'autre sens?
Merci.
Shao
Vous devez analyser chaque octet en nombre et utiliser cette valeur pour obtenir un caractère, comme ceci:
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";
Edit: Oui, votre string2Bin
actuel peut être écrit plus rapidement:
function string2Bin(str) {
var result = [];
for (var i = 0; i < str.length; i++) {
result.Push(str.charCodeAt(i).toString(2));
}
return result;
}
Mais en regardant la documentation que vous avez liée, je pense que la méthode setBytesParameter
s'attend à ce que le tableau blob contienne les nombres décimaux, pas une chaîne bit, vous pouvez donc écrire quelque chose comme ceci:
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
Il suffit de apply
votre tableau d'octets à String.fromCharCode
. Par exemple
String.fromCharCode.apply(null, [102, 111, 111])
est égal à "foo".
Avertissement: fonctionne pour les tableaux de moins de 65535. Les documents MDN ici .
Ce string2Bin peut être écrit même plus / de manière succincte, et sans aucune boucle, pour démarrer!
function string2Bin ( str ) {
return str.split("").map( function( val ) {
return val.charCodeAt( 0 );
} );
}
Essayez la nouvelle API de codage de texte:
// 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);
Je pense que ce serait plus efficace:
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('');
}
Chaîne en tableau d'octets: "FooBar".split('').map(c => c.charCodeAt(0));
Tableau d'octets en chaîne: [102, 111, 111, 98, 97, 114].map(c => String.fromCharCode(c)).join('');
Même si je suis un peu en retard, j'ai pensé qu'il serait intéressant pour les futurs utilisateurs de partager certaines implémentations monolithes que j'ai réalisées avec ES6.
Une chose que j'estime importante en fonction de votre environnement et/et de l'utilisation que vous ferez des données est de conserver la valeur d'octet complète. Par exemple, (5).toString(2)
vous donnera 101
, mais la conversion binaire complète est en réalité 00000101
. C'est pourquoi vous devrez peut-être créer une implémentation leftPad
pour renseigner l'octet de chaîne avec des zéros non significatifs. Mais vous n’en aurez peut-être pas besoin du tout, comme le montrent d’autres réponses.
Si vous exécutez l'extrait de code ci-dessous, vous verrez que la première sortie est la conversion de la chaîne abc
en un tableau d'octets, et juste après la re-transformation de ce tableau en chaîne correspondante.
// 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))
Cela devrait fonctionner:
String.fromCharCode(...array);
Ou
String.fromCodePoint(...array)
Il est trop tard pour répondre, mais si votre entrée est sous la forme d'octets ASCII, vous pouvez essayer cette solution:
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));
}
Nous n'avons trouvé aucune solution qui fonctionnerait avec les caractères UTF-8. String.fromCharCode
est bon jusqu'à ce que vous rencontriez un caractère de 2 octets.
Par exemple Hüser viendra comme [0x44,0x61,0x6e,0x69,0x65,0x6c,0x61,0x20,0x48,0xc3,0xbc,0x73,0x65,0x72]
Mais si vous le parcourez avec String.fromCharCode
, vous aurez Hüser car chaque octet sera converti séparément en un caractère.
J'utilise actuellement la solution suivante:
function pad(n) { return (n.length < 2 ? '0' + n : n); }
function decodeUtf8(data) {
return decodeURIComponent(
data.map(byte => ('%' + pad(byte.toString(16)))).join('')
);
}
J'avais des tableaux d'octets déchiffrés avec des caractères de remplissage et d'autres éléments dont je n'avais pas besoin, alors j'ai fait ceci (probablement pas parfait, mais cela fonctionne pour mon utilisation limitée)
var junk = String.fromCharCode.apply(null, res).split('').map(char => char.charCodeAt(0) <= 127 && char.charCodeAt(0) >= 32 ? char : '').join('');