我有一些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的秘密共享算法传递的字节!):
其他回答
试试这些函数,
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致敬
var decodedString = decodeURIComponent(escape(String.fromCharCode(...new Uint8Array(err)))); var obj = JSON.parse(decodedString);
做什么@Sudhir说,然后得到一个字符串,逗号分隔的数字列表使用:
for (var i=0; i<unitArr.byteLength; i++) {
myString += String.fromCharCode(unitArr[i])
}
这会给你想要的字符串, 如果还相关的话
如果你不能使用TextDecoder API,因为它不支持IE:
你可以使用Mozilla开发者网络网站推荐的faststsmallsttextencoderdecoder polyfill; 你也可以在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);
我很沮丧地看到,人们没有显示如何双向或显示事情的工作在不平凡的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的秘密共享算法传递的字节!):
推荐文章
- 我如何使用Jest模拟JavaScript的“窗口”对象?
- 我如何等待一个承诺完成之前返回一个函数的变量?
- 在JavaScript中根据键值查找和删除数组中的对象
- 使嵌套JavaScript对象平放/不平放的最快方法
- 如何以及为什么'a'['toUpperCase']()在JavaScript工作?
- 有Grunt生成index.html不同的设置
- 文档之间的区别。addEventListener和window。addEventListener?
- 如何检查动态附加的事件监听器是否存在?
- 如何写setTimeout与参数Coffeescript
- 将JavaScript字符串中的多个空格替换为单个空格
- JavaScript: override alert()
- 重置setTimeout
- 如何确保<select>表单字段被禁用时提交?
- jQuery有不聚焦的方法吗?
- 反应钩子-正确的方式清除超时和间隔