function pack(bytes) {
var str = "";
for(var i = 0; i < bytes.length; i += 2) {
var char = bytes[i] << 8;
if (bytes[i + 1])
char |= bytes[i + 1];
str += String.fromCharCode(char);
}
return str;
}
function unpack(str) {
var bytes = [];
for(var i = 0; i < str.length; i++) {
var char = str.charCodeAt(i);
bytes.push(char >>> 8);
bytes.push(char & 0xFF);
}
return bytes;
}
var tests = [
[],
[126, 0],
[0, 65],
[12, 34, 56],
[0, 50, 100, 150, 200, 250]
];
console.log("starting tests");
tests.forEach(function(v) {
var p = pack(v);
console.log(v, p, unpack(p));
});
输出的结果是:
starting tests
[] "" []
[126, 0] "縀" [126, 0]
[0, 65] "A" [0, 65]
[12, 34, 56] "ఢ㠀" [12, 34, 56, 0]
[0, 50, 100, 150, 200, 250] "2撖죺" [0, 50, 100, 150, 200, 250]
我有我想要反馈的一些信息:
这是我第一次使用按位运算符。请问这是应该怎么做的吗?
可以提高速度吗?
在编码然后解码具有奇数个数的数组时,你们能想到任何丢弃最后0个字节的方法吗?字节? (请参阅测试#4)
#1 楼
function pack(bytes) {
var str = "";
// You could make it faster by reading bytes.length once.
for(var i = 0; i < bytes.length; i += 2) {
// If you're using signed bytes, you probably need to mask here.
var char = bytes[i] << 8;
// (undefined | 0) === 0 so you can save a test here by doing
// var char = (bytes[i] << 8) | (bytes[i + 1] & 0xff);
if (bytes[i + 1])
char |= bytes[i + 1];
// Instead of using string += you could push char onto an array
// and take advantage of the fact that String.fromCharCode can
// take any number of arguments to do
// String.fromCharCode.apply(null, chars);
str += String.fromCharCode(char);
}
return str;
}
function unpack(str) {
var bytes = [];
for(var i = 0; i < str.length; i++) {
var char = str.charCodeAt(i);
// You can combine both these calls into one,
// bytes.push(char >>> 8, char & 0xff);
bytes.push(char >>> 8);
bytes.push(char & 0xFF);
}
return bytes;
}
所以要全部放在一起
function pack(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);
}
function unpack(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;
}
评论
\ $ \ begingroup \ $
请注意,String.fromCharCode.apply(null,chars);如果chars的长度大于65536,将在使用JavaScriptCore(即Safari)的浏览器中引发“ RangeError:超出最大调用堆栈大小”异常,并将完全锁定在比该长度稍小的数组上。完整的解决方案要么将字符串直接推入数组,要么使用fromCharCode的分块版本。我怀疑前者在Safari中速度更快。看到bugs.webkit.org/show_bug.cgi?id=80797
\ $ \ endgroup \ $
–马修
2012年12月12日12:03
评论
关于3.,只需在打包数组的末尾添加一个前哨,指示是否应包含最后一个字节。好主意。我将在开始指示长度处有2个字节,但是这会将长度限制为65535。使用您的方法,我可以得到更多。不是我需要它,但是打破障碍总是很高兴。
到底为什么要在客户端对字节进行编码?似乎应该在服务器上执行。
谁说那是客户端?
我已经使用了这段代码,将0值传递给它时似乎出现了问题,它们被转换为省略,从而使将32位浮点数打包为4个字符是不可靠的。有什么解决办法吗?