简体   繁体   English

在javascript中将字节数组转换为字符串

[英]Converting byte array to string in javascript

How do I convert a byte array into a string?如何将字节数组转换为字符串?

I have found these functions that do the reverse:我发现这些功能相反:

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;
}

But how do I get the functions working the other way?但是如何让功能以另一种方式工作?

Thanks.谢谢。

Shao

You need to parse each octet back to number, and use that value to get a character, something like this:您需要将每个八位字节解析回数字,并使用该值来获取一个字符,如下所示:

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: Yes, your current string2Bin can be written more shortly:编辑:是的,您当前的string2Bin可以更短地编写:

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

But by looking at the documentation you linked, I think that the setBytesParameter method expects that the blob array contains the decimal numbers, not a bit string , so you could write something like this:但是通过查看您链接的文档,我认为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

ES6 update ES6 更新

Now, string 'foo' also equals String.fromCharCode(...[102, 111, 111])现在,字符串 'foo' 也等于String.fromCharCode(...[102, 111, 111])

Original answer原始答案

Simply apply your byte array to String.fromCharCode .只需apply您的字节数组应用于String.fromCharCode For example例如

String.fromCharCode.apply(null, [102, 111, 111]) equals 'foo'. String.fromCharCode.apply(null, [102, 111, 111])等于 'foo'。

MDN docs here . MDN 文档在这里

Caveat: works for arrays shorter than 65535 - MDN docs here .警告:适用于短于 65535 的数组 - MDN docs here

Try the new Text Encoding API:尝试新的文本编码 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);

This should work:这应该有效:

String.fromCharCode(...array);

Or或者

String.fromCodePoint(...array)

That string2Bin can be written even more succinctly, and without any loops, to boot!那个 string2Bin 可以写得简洁,没有任何循环,启动!

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

I think this would be more efficient:我认为这会更有效:

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('');
}

Even if I'm a bit late, I thought it would be interesting for future users to share some one-liners implementations I did using ES6.即使我有点晚了,我认为未来的用户分享一些我使用 ES6 所做的单行实现会很有趣。

One thing that I consider important depending on your environment or/and what you will do with with the data is to preserve the full byte value.根据您的环境或/以及您将如何处理数据,我认为重要的一件事是保留完整的字节值。 For example, (5).toString(2) will give you 101 , but the complete binary conversion is in reality 00000101 , and that's why you might need to create a leftPad implementation to fill the string byte with leading zeros.例如, (5).toString(2)会给你101 ,但完整的二进制转换实际上是00000101 ,这就是为什么你可能需要创建一个leftPad实现来用前导零填充字符串字节。 But you may not need it at all, like other answers demonstrated.但是您可能根本不需要它,就像其他答案所展示的那样。

If you run the below code snippet, you'll see the first output being the conversion of the abc string to a byte array and right after that the re-transformation of said array to it's corresponding string.如果您运行以下代码片段,您将看到第一个输出是将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))

String to byte array: "FooBar".split('').map(c => c.charCodeAt(0));字符串到字节数组: "FooBar".split('').map(c => c.charCodeAt(0));

Byte array to string: [102, 111, 111, 98, 97, 114].map(c => String.fromCharCode(c)).join('');字节数组到字符串: [102, 111, 111, 98, 97, 114].map(c => String.fromCharCode(c)).join('');

Too late to answer but if your input is in form of ASCII bytes, then you could try this solution:回答为时已晚,但如果您的输入是 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');

Didn't find any solution that would work with UTF-8 characters.没有找到任何适用于 UTF-8 字符的解决方案。 String.fromCharCode is good until you meet 2 byte character.在遇到 2 字节字符之前, String.fromCharCode是好的。

For example Hüser will come as [0x44,0x61,0x6e,0x69,0x65,0x6c,0x61,0x20,0x48,0xc3,0xbc,0x73,0x65,0x72]例如Hüser将作为[0x44,0x61,0x6e,0x69,0x65,0x6c,0x61,0x20,0x48,0xc3,0xbc,0x73,0x65,0x72]

But if you go through it with String.fromCharCode you will have Hüser as each byte will be converted to a char separately.但是,如果您使用String.fromCharCode完成它,您将拥有Hüser ,因为每个字节将分别转换为 char。

Solution解决方案

Currently I'm using following solution:目前我正在使用以下解决方案:

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('');

If your array is encoded in UTF-8 and you can't use the TextDecoder API because it is not supported on IE :如果您的数组以 UTF-8 编码并且您不能使用TextDecoder API ,因为IE 不支持它

  1. You can use the FastestSmallestTextEncoderDecoder polyfill recommended by the Mozilla Developer Network website ;你可以使用Mozilla Developer Network 网站推荐的FastestSmallestTextEncoderDecoder polyfill
  2. You can use this function also provided at the MDN website :您也可以使用MDN 网站上提供的此功能:

 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);

> const stringToBin = (str) => [...str].map(item=>item.charCodeAt())
> undefined
> stringToBin('hello')
> (5) [104, 101, 108, 108, 111]
> const binToString = (array) => String.fromCharCode(...array) 
> undefined
> binToString(stringToBin('hello'))
> 'hello'

What you are looking for is String.fromCharCode您正在寻找的是String.fromCharCode

What you want to do is loop through the array of bytes (represented as integers), create the string equivalent and add it to the result:您要做的是遍历字节数组(表示为整数),创建等效字符串并将其添加到结果中:

 function bin2String(array) { var result = ""; for (const char of array) { result += String.fromCharCode(char); } return result; } console.log(bin2String([116, 104, 101, 32, 114, 101, 115, 117, 108, 116]));

You can also use the Array.Map function to convert the array of bytes into an array of strings, then join them all.您还可以使用 Array.Map 函数将字节数组转换为字符串数组,然后将它们全部连接起来。

 function string2Bin(array) { return array.map(byte => String.fromCharCode(byte)).join(""); } console.log(string2Bin([116, 104, 101, 32, 114, 101, 115, 117, 108, 116]));

我发现的最简单的解决方案是:

var text = atob(byteArray);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM