我有一些UTF-8编码的数据生活在Javascript Uint8Array元素的范围内。是否有一种有效的方法来解码这些到一个常规的javascript字符串(我相信javascript使用16位Unicode)?我不想一次添加一个字符,因为字符串连接会变得CPU密集。


当前回答

我很沮丧地看到,人们没有显示如何双向或显示事情的工作在不平凡的UTF8字符串。我在codereview.stackexchange.com上找到了一个帖子,其中有一些运行良好的代码。我用它把古老的符文转换成字节,在字节上测试一些加密,然后把东西转换回字符串。工作代码在github这里。为了清晰起见,我重命名了这些方法:

// https://codereview.stackexchange.com/a/3589/75693
function bytesToSring(bytes) {
    var chars = [];
    for(var i = 0, n = bytes.length; i < n;) {
        chars.push(((bytes[i++] & 0xff) << 8) | (bytes[i++] & 0xff));
    }
    return String.fromCharCode.apply(null, chars);
}

// https://codereview.stackexchange.com/a/3589/75693
function stringToBytes(str) {
    var bytes = [];
    for(var i = 0, n = str.length; i < n; i++) {
        var char = str.charCodeAt(i);
        bytes.push(char >>> 8, char & 0xFF);
    }
    return bytes;
}

单元测试使用这个UTF-8字符串:

    // http://kermitproject.org/utf8.html
    // From the Anglo-Saxon Rune Poem (Rune version) 
    const secretUtf8 = `ᚠᛇᚻ᛫ᛒᛦᚦ᛫ᚠᚱᚩᚠᚢᚱ᛫ᚠᛁᚱᚪ᛫ᚷᛖᚻᚹᛦᛚᚳᚢᛗ
ᛋᚳᛖᚪᛚ᛫ᚦᛖᚪᚻ᛫ᛗᚪᚾᚾᚪ᛫ᚷᛖᚻᚹᛦᛚᚳ᛫ᛗᛁᚳᛚᚢᚾ᛫ᚻᛦᛏ᛫ᛞᚫᛚᚪᚾ
ᚷᛁᚠ᛫ᚻᛖ᛫ᚹᛁᛚᛖ᛫ᚠᚩᚱ᛫ᛞᚱᛁᚻᛏᚾᛖ᛫ᛞᚩᛗᛖᛋ᛫ᚻᛚᛇᛏᚪᚾ᛬`;

请注意,字符串长度只有117个字符,但编码时字节长度为234。

如果我取消console.log行注释,我可以看到解码的字符串与编码的字符串相同(通过Shamir的秘密共享算法传递的字节!):

其他回答

到目前为止,对我来说最简单的方法是:


//1. Create or fetch the Uint8Array to use in the example
const bufferArray = new Uint8Array([10, 10, 10])

//2. Turn the Uint8Array into a regular array
const array = Array.from(bufferArray);

//3. Stringify it (option A)
JSON.stringify(array);


//3. Stringify it (option B: uses @serdarsenay code snippet to decode each item in array)
let binArrayToString = function(binArray) {
    let str = "";
    for (let i = 0; i < binArray.length; i++) {        
        str += String.fromCharCode(parseInt(binArray[i]));
    }
    return str;
}

binArrayToString(array);

我正在使用这个Typescript代码片段:

function UInt8ArrayToString(uInt8Array: Uint8Array): string
{
    var s: string = "[";
    for(var i: number = 0; i < uInt8Array.byteLength; i++)
    {
        if( i > 0 )
            s += ", ";
        s += uInt8Array[i];
    }
    s += "]";
    return s;
}

如果需要JavaScript版本,则删除类型注释。 希望这能有所帮助!

以下是我使用的方法:

var str = String.fromCharCode.apply(null, uint8Arr);

试试这些函数,

var JsonToArray = function(json)
{
    var str = JSON.stringify(json, null, 0);
    var ret = new Uint8Array(str.length);
    for (var i = 0; i < str.length; i++) {
        ret[i] = str.charCodeAt(i);
    }
    return ret
};

var binArrayToJson = function(binArray)
{
    var str = "";
    for (var i = 0; i < binArray.length; i++) {
        str += String.fromCharCode(parseInt(binArray[i]));
    }
    return JSON.parse(str)
}

来源:https://gist.github.com/tomfa/706d10fed78c497731ac,向Tomfa致敬

在节点“缓冲区实例也是Uint8Array实例”,所以buf.toString()在这种情况下工作。