Как преобразовать массив байтов в строку?
Я нашел эти функции, которые делают обратное:
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;
}
Но как мне заставить функции работать по-другому?
Благодарю.
Шао
javascript
casting
user385579
источник
источник
Ответы:
Вам нужно преобразовать каждый октет обратно в число и использовать это значение для получения символа, примерно так:
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";
Изменить: Да, ваш текущий
string2Bin
можно записать короче:function string2Bin(str) { var result = []; for (var i = 0; i < str.length; i++) { result.push(str.charCodeAt(i).toString(2)); } return result; }
Но, глядя на связанную документацию, я думаю, что
setBytesParameter
метод ожидает, что массив blob будет содержать десятичные числа, а не битовую строку , поэтому вы могли бы написать что-то вроде этого: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
источник
String.fromCharCode.apply(String, array)
небезопасно для очень длинных строк в Safari. В JavaScriptCore есть проблема, которая означает, что функции не могут принимать более 65536 аргументов, в противном случае будет выбрано RangeError. Он также блокирует браузер для массивов немного меньшего размера. См. Bugs.webkit.org/show_bug.cgi?id=80797bin2String([0xE2, 0x98, 0xB9])
Просто
apply
ваш байтовый массивString.fromCharCode
. НапримерString.fromCharCode.apply(null, [102, 111, 111])
равно "foo".Предостережение: работает для массивов короче 65535. Документация MDN здесь .
источник
Попробуйте новый API кодирования текста:
// 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);
источник
Это должно работать:
String.fromCharCode(...array);
Или же
String.fromCodePoint(...array)
источник
Этот string2Bin можно записать еще более кратко и без каких-либо циклов!
function string2Bin ( str ) { return str.split("").map( function( val ) { return val.charCodeAt( 0 ); } ); }
источник
Думаю, было бы эффективнее:
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(''); }
источник
Даже если я немного опоздаю, я подумал, что будущим пользователям будет интересно поделиться некоторыми однострочными реализациями, которые я сделал с помощью ES6.
Одна вещь, которую я считаю важной в зависимости от вашей среды или / и того, что вы будете делать с данными, - это сохранить полное байтовое значение. Например,
(5).toString(2)
даст вам101
, но полное двоичное преобразование на самом деле есть00000101
, и поэтому вам может потребоваться создатьleftPad
реализацию для заполнения байта строки ведущими нулями. Но, возможно, вам это вообще не понадобится, как показали другие ответы.Если вы запустите приведенный ниже фрагмент кода, вы увидите, что первым результатом является преобразование
abc
строки в массив байтов и сразу после этого повторное преобразование указанного массива в соответствующую строку.// 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))
источник
Строка в байтовый массив:
"FooBar".split('').map(c => c.charCodeAt(0));
Байтовый массив в строку:
[102, 111, 111, 98, 97, 114].map(c => String.fromCharCode(c)).join('');
источник
Слишком поздно отвечать, но если вы введены в виде байтов ASCII, вы можете попробовать это решение:
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)); }
источник
Если вы используете node.js, вы можете сделать это:
yourByteArray.toString('base64');
источник
Не нашел решения, которое бы работало с символами UTF-8.
String.fromCharCode
хорошо, пока вы не встретите 2-байтовый символ.Например, Хюзер придет как
[0x44,0x61,0x6e,0x69,0x65,0x6c,0x61,0x20,0x48,0xc3,0xbc,0x73,0x65,0x72]
Но если вы пройдете через это, у
String.fromCharCode
вас будет Hüser, поскольку каждый байт будет преобразован в char отдельно.Решение
В настоящее время я использую следующее решение:
function pad(n) { return (n.length < 2 ? '0' + n : n); } function decodeUtf8(data) { return decodeURIComponent( data.map(byte => ('%' + pad(byte.toString(16)))).join('') ); }
источник
У меня было несколько расшифрованных байтовых массивов с символами заполнения и другими вещами, которые мне не нужны, поэтому я сделал это (вероятно, не идеально, но это работает для моего ограниченного использования)
var junk = String.fromCharCode.apply(null, res).split('').map(char => char.charCodeAt(0) <= 127 && char.charCodeAt(0) >= 32 ? char : '').join('');
источник
Если ваш массив закодирован в UTF-8 и вы не можете использовать API TextDecoder, потому что он не поддерживается в 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);
источник
Самое простое решение, которое я нашел:
var text = atob(byteArray);
источник