将javascript中的数字压缩为二进制格式

时间:2013-01-13 23:21:11

标签: javascript compression

我需要在尽可能少的数据中将以下内容转换为二进制格式(以后再补偿)。

my_arr = [
        [128,32 ,22,23],
        [104,53 ,21,25],
        [150,55 ,79,23],
        [104,101,23,8 ],
        [57 ,117,13,21],
        [37 ,135,21,20],
        [81 ,132,23,6 ],
        [81 ,138,7 ,8 ],
        [97 ,138,7 ,8 ]...

数字不超过399

如果我为每个数字使用0(8 0&a 39 =一行= 8)和1作为分隔符,则第一行如下所示: 010010000000011000100110010011001000 对于像99这样的数字来说,这真的很长

如果我将每个数字填充为三位数并将每个数字依次转换为实际二进制数,则第一行如下所示: 000100101000000000110010000000100010000000100011 这个数字为12个字符。

由于第一个char赢得了4或者以上,我可以通过将0视为00,1将01视为10,将3视为11来节省两个挖掘。因此,每个数字为10个字符 总的来说,这会将尺寸缩小到第一个选项的约90%(平均而言)但是有更短的方式吗?

编辑:是一个1和1的字符串...并且它不需要比原始整数短......只是用尽可能短的方式来编写它2个符号

2 个答案:

答案 0 :(得分:5)

如果值均匀分布在0到399之间,那么一个相当不错的编码将采用三个值并将它们编码为基本400三位整数。即val1 + 400 * val2 + 400 * 400 * val3。然后该整数将很好地适合26位。四个连续的26位值将适合13个字节。然后,每个值平均得到13/12字节。

除非值的分布存在偏差,或者如果存在重复或相关性,否则这将与您能够做的一样好,在这种情况下,您可以更多地压缩它们。

要处理细节,您可以使用编码序列中的字节数来确定值的数量,这可能不是三的倍数。如果它不是三的倍数,则最后将有一个或两个值,每个编码为9位。由于需要8位来从18位增加到26位以添加值,因此计数中没有歧义。

答案 1 :(得分:1)

一个很好的起点是创建1和0的恒定长度块,这使您可以轻松解码字符串。

二进制的400是110010000,需要9个字符来编码每个数字,因为它的二进制表示填充为零填充到恒定长度。

编码第一行:

var padTo9 = function( bin ){ 
    while( bin.length<9 ){ bin = "0" + bin; } 
    return bin; 
}
[128,32 ,22,23].map( function(i){ return padTo9( i.toString(2) ) }).join('');

/* result:
"010000000000100000000010110000010111"
*/

解码

"010000000000100000000010110000010111".match(/[0-1]{9}/g).map( function(i){ return parseInt( i, 2 ) });
/* result:
[128, 32, 22, 23]
*/

我认为获得更短字符串的唯一方法是使用可变块长度,这需要添加一些控制符号来告诉解码器后续数字以特定数量的字符编码。但是这些符号必须大于400且仍然长9个字符,所以我认为这对随机分布的数据没有帮助。