• 将js/css脚本放到png图片中的实践。


     http://blog.csdn.net/zswang/article/details/7061560

    将js/css脚本放到png图片中的实践。

    标签: 脚本functionxmlhttprequesturl浏览器加密
     分类:
    起因
    高级浏览器支持data协议,如:
    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC"/>
    <script src="data:text/javascript;base64,YWxlcnQoJ2h0dHA6Ly93ZWliby5jb20venN3YW5nJyk7"></script>
    不光是<img>标签,<script>、<style>、<iframe>也都支持data协议;
    data协议可以表示图片、文本、音视频等各种二进制数据
    另html5的canvas除了绘制图像,还能读写每一个像素值
    一种把脚本存到图像中的思路就有了。
     
    经过
    最初的尝试就是把每个字符挨个放到像素的r、g、b、a里
    需要处理的问题:
    1、计算图片的尺寸;
         本来想用高度为1,宽度为字符串长度的尺寸,但考虑到压缩比和美观,所以决定生成正方形。
            var pixel = Math.ceil((text.length + 3) / 4);
            var size = Math.ceil(Math.sqrt(pixel));
    2、每个字符unicode编码,可能会超出255;
         那就得将字符串转成ascii码
    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);
            }
        );
    }
    3、还得考虑异步的问题
        var img = document.createElement('img');
        img.onload = function(){
            //...;
        }
     
    第一轮demo做完,结果测试不符合预期。跟踪发现:还原的数据和编码的数据相差较大。
    开始在怀疑是不是img标签绘制到canvas变成了有损压缩,如果真是这样,那整个方案就是不可行;
    坚持“不抛弃,不放弃”+定位问题最简化的原则,逐步缩小范围,最终锁定是由于alpha值影响还原。
    解决方案就是:一个像素存放三个字符并将alpha固定为255。

    第二轮demo测试符合预期。
     
    总结
    build流程:
    1、字符串转换成ascii码;
    2、创建足够存储空间的canvas;
    3、将字符填入到像素中(忽略alpha值);
    4、获取data url;
         canvas.toDataURL("image/png");
    5、存为png图片。
    代码示例
    [html] view plain copy
     
    1. <textarea id="base64"></textarea>  
    2. <script>  
    3. function encodeUTF8(str) {  
    4.     return String(str).replace(  
    5.         /[u0080-u07ff]/g,  
    6.         function(c) {  
    7.             var cc = c.charCodeAt(0);  
    8.             return String.fromCharCode(0xc0 | cc >> 6, 0x80 | cc & 0x3f);  
    9.         }  
    10.     ).replace(  
    11.         /[u0800-uffff]/g,  
    12.         function(c) {  
    13.             var cc = c.charCodeAt(0);  
    14.             return String.fromCharCode(0xe0 | cc >> 12, 0x80 | cc >> 6 & 0x3f, 0x80 | cc & 0x3f);  
    15.         }  
    16.     );  
    17. }  
    18.   
    19. function request(url, loaded) {  
    20.     var xmlhttp = new XMLHttpRequest();  
    21.     xmlhttp.onreadystatechange = function() {  
    22.         if (xmlhttp.readyState == 4)  
    23.             if (xmlhttp.status == 200)  
    24.                 loaded(xmlhttp);  
    25.     }  
    26.     xmlhttp.open("GET", url, true);  
    27.     xmlhttp.send();  
    28. }  
    29.   
    30. void function(){  
    31.     var source = 'tangram-1.5.0.js';  
    32.     request(source, function(xmlhttp){  
    33.         var text = encodeUTF8(xmlhttp.responseText);  
    34.         var pixel = Math.ceil((text.length + 2) / 3); // 1一个像素存3个字节,  
    35.         var size = Math.ceil(Math.sqrt(pixel));  
    36.         //console.log([text.length, pixel, size, size * size * 3]);  
    37.         var canvas = document.createElement('canvas');  
    38.         canvas.width = canvas.height = size;  
    39.         var context = canvas.getContext("2d"),  
    40.             imageData = context.getImageData(0, 0, canvas.width, canvas.height),  
    41.             pixels = imageData.data;  
    42.         for(var i = 0, j = 0, l = pixels.length; i < l; i++){  
    43.             if (i % 4 == 3) { // alpha会影响png还原  
    44.                 pixels[i] = 255;  
    45.                 continue;  
    46.             }  
    47.             var code = text.charCodeAt(j++);  
    48.             if (isNaN(code)) break;  
    49.             pixels[i] = code;  
    50.         }  
    51.         context.putImageData(imageData, 0, 0);  
    52.         document.getElementById('base64').value = canvas.toDataURL("image/png");  
    53.     });  
    54. }();  
    55. </script>  
    编译结果


    调用流程:
    1、加载png;
    2、将png原尺寸绘制到canvas中;
    3、读取像素中的字符串;
    4、生成相应协议的data url使用。
    代码示例
    [html] view plain copy
     
    1. <script>  
    2. void function(){  
    3.     var source = 'tangram-1.5.0.png';  
    4.     var img = document.createElement('img');  
    5.     img.onload = function(){  
    6.         var canvas = document.createElement('canvas');  
    7.         canvas.width = img.width;  
    8.         canvas.height = img.height;  
    9.   
    10.         var context = canvas.getContext("2d");  
    11.         context.drawImage(img, 0, 0);  
    12.         var imageData = context.getImageData(0, 0, canvas.width, canvas.height),  
    13.             pixels = imageData.data;  
    14.   
    15.         var script = document.createElement('script');  
    16.         var buffer = [];  
    17.         for (var i = 0, l = pixels.length; i < l; i++) {  
    18.             if (i % 4 == 3) continue; // alpha会影响png还原  
    19.             if (!pixels[i]) break;  
    20.             buffer.push(String.fromCharCode(pixels[i]));  
    21.         }  
    22.         script.src = 'data:text/javascript;charset=utf-8,' + encodeURIComponent(buffer.join(''));  
    23.         document.body.appendChild(script);  
    24.         script.onload = function(){  
    25.             alert(T.date.format(new Date, 'yyyy年M月d日'));  
    26.         }  
    27.         img = null;  
    28.     }  
    29.     img.src = source;  
    30. }();  
    31. </script>  



    优势
    1、压缩率大(50%);
    2、隐蔽性相对高;
         可以设计加密的脚本,用公钥解锁;
    3、减少网络请求;
         可以将多个图片、脚本放到一个png里,囧;
    4、一种二进制处理文本的思路。
     
    劣势
    1、解码会使用更多的cpu,导致加载缓慢;
    2、不支持低端浏览器;
    3、开发维护成本更高。
     
    总结
    1、不具实战性;
    2、在数据加密传输方面可以近一步研究。
     
    相关demo
     
     
    delphi lazarus opengl 网页操作自动化, 图像分析破解,游戏开发
  • 相关阅读:
    Statspack之十四"log file sync" 等待事件
    log file sync(日志文件同步) 与 Log file parallel write 等待事件(1)
    OWI诊断的步骤(基础)
    linux下防火墙配置
    linux中oracle开机启动(2)
    Linux开机自动启动ORACLE设置
    linux find mtime参数详解
    linux 下 rman自动备份
    JSTL 标签库 下载及配置
    JSTL I18N 格式标签库 使用之一_____数字日期格式化
  • 原文地址:https://www.cnblogs.com/delphi-xe5/p/5802692.html
Copyright © 2020-2023  润新知