我正在尝试开发一种适用于二进制的新型JavaScript压缩器,不像常规缩小器(如Closure Compiler)或基于字典的打包器(如JScrush)。
以下是这个想法:
我想压缩JS代码alert(123)
。
- 压缩器获取每个字符并将其从ASCII转换为二进制:
01100001 01101100 01100101 01110010 01110100 00101000 00110001 00110010 00110011 00101001
- 然后,它会删除每个字符的高位,因为它在ASCII
中始终为01100001 1101100 1100101 1110010 1110100 0101000 0110001 0110010 0110011
- 然后,它使用剩余的位
创建一个长字符串"110000111011001100101111001011101000101000011000101100100110011"
- 然后,它以8位块的形式剪切该字符串
11000011 10110011 00101111 00101110 10001010 00011000 10110010 01100110
- 然后,它将每个块转换为8位字符
ó/.²f
解码器只需要反过来就可以恢复原来的JS。
所以我用JavaScript编写了这个编码器和解码器,它就像一个魅力:
http://xem.github.io/JSciissors/
如果你把11k个字符放在最上面,你会在底部获得10k个字符,如果你执行底部代码,它就可以了。酷!
但是,如果将编码的脚本保存在文本文件中,则会出现问题:
- 如果以UTF-8保存,每个非ASCII字符将存储在2个字节中,压缩文件将大于原始文件。
- 如果你把它保存在latin-1(又名iso-8859-1)中,那么文件大小就可以了(每个字符都适合一个字节),但是当你执行它时,它不起作用,因为解码不再准确:
alers�123)
我对此结果感到惊讶,因为UTF8的前256个代码点与Latin-1前256个代码点相匹配。
如果将其保存为ANSI(a.k.a windows-1252),则会出现同样的问题。
有人可以解释一下这里发生了什么,为什么它没有按预期工作,以及是否有解决方案?
非常感谢!
PS:这是JS中的编码器和解码器(但我认为问题不在JS中,而是在转码中......)
// Encoder
// @param d: original JS code
function e(d,b,f,c,a){b=a="";for(f in d+=";")c=d.charCodeAt(f),a+=(1e6+c.toString(2)).slice(-7);for(;7<a.length;)c=String.fromCharCode(parseInt(a.substring(0,8),2)),b+=c,a=a.slice(8);return b}
// Decoder:
a='(encoded JS code)';b=c='';for(i=0;(original JS length)>i;i++)b+=(1e7+a.charCodeAt(i).toString(2)).slice(-8),c+=String.fromCharCode(parseInt(b.substr(i*7,7),2));eval(c)