把你的 JS 变成一张图 ???

744天前2180

前段时间和 Kiosr 聊天的时候,他说玩了一个很鬼畜的东西。

直接看他博客源码,发现 JS 只有如下几句话:

<scrpit>Function('‌‌‍‌‍​‌‌​‍​‍​​‌‍‍​‌‌‍‌‍‌‌‌‌‍‍‌‍​‌‌​‌‍‍‌‌‍‌‍‍​‍‍​‌‍​‌​‍‍‌‌‍‌‌‍‌‍​‌‌​‍​‍​​‌‍​‍​‌‌‌‍‌‌‌​‍​‌‍​​‌‌‍​‌​‍‍‌‌‌‍‍‌‌‍‌​‌‌​‌‍‍​​‍​‌‍‌​​‌‌‍​‌​‍‍‌‍‍​‌‍‌‌‌‍‍‌‌‍‌‌‍‍​‌‌​​‍​‌‍‌‌​‌‌‍‌​‌‍‌‍​‌‌‌‌‍‌‌‍‌‌‌‍‍‌‌​​‍‍‌‍​‌​‍‌‍‌‌‌‍​‌‌‌​‌‍‌‌‌​‌‌‌‍​‌‍‌‌‌‍‌‌‍‌‌‌‍‍‌‌​​‍‍​​‍​‍‌‍​‌‍​‌‌‍‍‌‌‍‌‍​‌‌​​‍​‍​‍‍‌​‍‌‍‌‍‌‍‌​‍​‍‍​‌‍‌‌​‍‍‌‌‌‍‍‌‌‍‌​‌‌​‌‍‍​​‌‌‍​​‍​‌‍‌‌​‍‍‌‍‍​‌‍‌‌‌‍‍‌‌‍‌‌‍‍​‌‌​​‌‌‍‌​​‍​‌‍‌‌​‌‌‍‌‌​‍‍‌‍‌‌‍‌‌‌‌​‌​​‌‍‌‍‍‌‌​‌‍‌‌‌‍​‌‌​​‍‍​​‍​‍​​‍‌‍‌​​‍​‍​‍‍‌​‍​‌‍‌‌​‍‍‌‍‌​‌​‍‌‍​‌‌‌‌​‍‌‌‍‌‌‍​‌‌‍‌‌‍‌‌​‍‍​‌‍​‌​‍​​​​​‍​​​​​‍‍‌​‍​‌‍​‌​‌‌‍‌‌​‍‍‌‍‌‌‍‌‌‌‌​‌​‍‌‌‍‌‌‍​‌‌‍‌‌‍‌‌‌​‌​‌‍​‌‌‌​‌‍​‌​‍‍​​​​​‍​​​​​‍​‌‍​​‍​‌‍‌​​‍‍‌​‍​‌‍‌‌​‌​​​​‍​‌​​‍‍‍‌‍​​‍‍‍‌‍‌​​‍‌‍‌‌​‍‌‍‌‌​‍‍​‌​‌​​‍‍‌‌‌‍‌‌‌​‍‍‌​​‌‌‌‌​‌‍‍​​‍‍‌‍​‌‌​​‌​​‌‍​‌‍‌​‍‍​‌‍​‍​‍​‌‌‍‌‌‌​‍‍‌​‌‍​‌‍‍‌‌‍​‌‍‌‌​‍‍‌‍​‌‍​‌‌‍​‌‍​​‍‍​‌‍​‌​‍‍‌‍‌​‌‍​‌‌‌​‌‍​‌​‍​‌‍‌‌​‍​‌‍‌‌​‍‍​​​‍‍‌​‍‍‌​‍‌‍‌‍‌‍‌​‍​‍‍​‌‍​​‌‌‍​‍​‍‍‌‍​‌‍‌‌‌‍‍‌‍‌‌‌​‌‍‍​​‍‌​​‌​‍​​​​‌​‌​‌‌‍​‍‌‌‍‌‍​‌‌‌​‍​‍‍‌‌‍​‍​‌‌‍​‍​‍‍‌​‌‍​‌‍‍‌‌‍​‌‍‌‌​‍‍​​​​​‍​‌‍​​‍‍‌​‍​‌‍​​‍‌​‍‌​‍‌‍‌‍‌‍‌​‍​‍‍​‌‍​​‌​‍​‍​‍​‍​‍​‌‍‌​​‌​​​​‍‌‍‌​​​‌‍​‍​‍‍‌‍​‌‍‌‌‌‍‍‌‍‌‌‌​‌‍‍​​‍‌‍‌​​‍‍​‌​‌​‍‍‌‌‍‌‍‌‍‌​‍​‍‍​‌‍​‌​‌​​​​‍​‍​​‍‌‍​‌​‍‌‍​‌​‍‍​‍‍​‍‍‌‌‍‌‌​‌​‍‍​​​‌​​‍​‌​‍‌‍​‍‍​​​​​‌​‌‌‍​‌​​​​​‍‍‌‍​‍‌‌‍‌‍‌​​‍‍‌‍​‌​‍‌​​‌‌‌‌​‍‍‌​​​​​‌​‍‌‌‍​‌​‍‍‌​‍‍​‍‍​​‍‍​​‌​‌​‌‌‍​‌​​​​​‍‍‌‍​‍‌‌‍‌‍‌​​‍‍‌‍​‌‌‌‌​‍‍‌​‍​‍‌‍​‌​‍‍​​‌​‍‍‌​‍​‌‍​​‍‍​‌​​​​‌​‌‌‍‌‌​​‍​‍​‍​‍​‍‍‌‌​‌‌​‌​‍‌‍‍‌‌‍‍‌‍‌​‍‍‌‍‌‍‌​‍‌‍‌‍‌‌​​‌‍‍​‌‍​‌‌​‍‌​​‌‍‌‍‌​‌‍‌‌​‍‍​‌‍‌‌​‍‍‌​‍‌​‍‌‍‌‌‌‌​‌‌‌‌​‍‌‍‍​‍​​‌‍​‌‌​‍​‌‍‍‌‌‍‌‌‍‌​‌‌‍‍‌‍‌‌‌‌​‍​​‌​‍‌‌‍‌‌‍​‌‌‍‌‌‍‌‌​‍‌‍‍‌‌‍‌‌‍‌​‍‍‌‍‌‍‍‌‍​‌‍‌‍​‌‌‍‌​​‌‌‍‌‍‌‌‌‌‍‍‌‍​‌‌​‌‍‍‌‌‍‌‍‍​‍‍​​‍‍‌‌‍‌​‌‍‌‌‌‌‍‍‌‍​‌‌​‌‍‍‌‌‍‌‍‍​‍‍​‌‍‍​‍‍​‌‍‍‌‌‍‌‌‍‌​‍‍‌​‍‍‌​‍‍​​‍‍‌‌‌​‍​‌‍‍‌‌‍‌‌‍‌​‍‍‌‍​‌​‍‌‍‌​‌​‌​‌​‍‌‍‍‌‌‍‌‌‍‍‌‌‍‍​‌​‍​‍​‍‍‍​‍​‍​‍​‌‍‍‌‌‍‌‌‍‌​‍‍‌​‌​‍‌‍​​‌​‍​‍‌‍‍​‌‌​‌‌​‌​​‌​​‍‍​‍​‍‌‍‌‌‍‌‍‌‌‌‍‌‍‌‍​‍‍‌‍​‌‍‍​‍‌‍‍​‍‍‌​​‌‍‍‌‍‌​‍​‍​‍'.replace(/.{4}/g,function(a){return String.fromCharCode(parseInt(a.replace(/./g,function(a){'‌‍‍​‌‍‌‌‌‍​‌‍‍​‌‍​‌‌‍‌‍​‌‍‍​‌‍‌‌‌‍‍‌‍‌';return{'​':'00','‌':'01','‍':'10','':'11'}[a]}),2))}))();</scrpit>

然后就没有任何引用 JS 文件的地方或语句了。

Kiosr 告诉我他把 JS 写在图片里了。

当时我是懵逼的,JS 写在图片里,什么骚操作?

于是抱着好奇心,找到了类似案例【原文】,实践了下:

创建图片流程:

字符串转换成 ascii 码;
创建足够存储空间的 canvas;
将字符填入到像素中(忽略 alpha 值);
获取 data url;
canvas.toDataURL( "image/png" );
存为 png 图片。

<textarea id="base64"></textarea>
<script>
function encodeUTF8(str) {
 return String(str).replace(
   /[\u0080-\u07ff]/g,
 function(c) {
   var cc = c.charCodeAt(0);
   return String.fromCharCode(0xc0 | cc >> 6, 0x80 | cc & 0x3f);
}).replace(
   /[\u0800-\uffff]/g,
 function(c) {
   var cc = c.charCodeAt(0);
   return String.fromCharCode(0xe0 | cc >> 12, 0x80 | cc >> 6 & 0x3f, 0x80 | cc & 0x3f);
});
}
function request(url, loaded) {
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == 4)
    if (xmlhttp.status == 200)
       loaded(xmlhttp);}
    xmlhttp.open("GET", url, true);
    xmlhttp.send();
}
void function(){
  var source = 'your.js';  //你的 JS 地址
  request(source, function(xmlhttp){
  var text = encodeUTF8(xmlhttp.responseText);
  var pixel = Math.ceil((text.length + 2) / 3); 
  var size = Math.ceil(Math.sqrt(pixel));
  var canvas = document.createElement('canvas');
  canvas.width = canvas.height = size;
  var context = canvas.getContext("2d"),
  imageData = context.getImageData(0, 0, canvas.width, canvas.height),
  pixels = imageData.data;
  for(var i = 0, j = 0, l = pixels.length; i < l; i++){
  if (i % 4 == 3) {
    pixels[i] = 255;
    continue;}
  var code = text.charCodeAt(j++);
    if (isNaN(code)) break;
    pixels[i] = code;}
  context.putImageData(imageData, 0, 0);
  document.getElementById('base64').value = canvas.toDataURL("image/png");
});
}();
</script>

调用加载流程:
加载 png;
将 png 原尺寸绘制到 canvas 中;
读取像素中的字符串;
生成相应协议的 data url 使用。

<script>
void function(){
  var source = 'your.png';  //你的图片地址
  var img = document.createElement('img');
  img.onload = function(){
  var canvas = document.createElement('canvas');
  canvas.width = img.width;
  canvas.height = img.height;
  var context = canvas.getContext("2d");
  context.drawImage(img, 0, 0);
  var imageData = context.getImageData(0, 0, canvas.width, canvas.height),
  pixels = imageData.data;
  var script = document.createElement('script');
  var buffer = [];
  for (var i = 0, l = pixels.length; i < l; i++) {
  if (i % 4 == 3) continue;
  if (!pixels[i]) break;
  buffer.push(String.fromCharCode(pixels[i]));}
  script.src = 'data:text/javascript;charset=utf-8,' + encodeURIComponent(buffer.join(''));
  document.body.appendChild(script);
  script.onload = function(){
  alert(T.date.format(new Date, 'yyyy 年 M 月 d 日'));}
  img = null;}
  img.src = source;
}();
</script>

同时注意,需要转换的 JS 里有中文的话,需要将中文的编码转为 Unicode 编码,否者无法显示正常中文。

最终我测试了下,大概原来不到 20KB 的 JS 文件可以压缩成了一张 10KB 左右的 PNG 图片,还是蛮 666 的,哈哈。

Kiosr 告诉我,他还在想看看怎么让它变成一张正常的图片,利用起来。

或者是分段式按需加载,每篇文章都有头图,也能利用起来,这样的话,每篇文章都可以拥有独特的效果。

我只能说太骚了,哈哈。

* 若非特殊说明,本站文章均为博主原创,码字不易,如需转载,请注明出处!有疑问可留言交流,谢谢。

Javascript分享15 

把你的 JS 变成一张图 ??? - Jdeal | Life is like a Design.