JavaScript奇淫基本功:dealing
责任编辑将用JavaScript同时实现“相片dealing”。
甚么是dealing?
将文档或其他统计数据载入相片的控制技术,称作“dealing”。
比如说上面这张图中,便暗藏着绝密重要信息,尽管看上去而已两张图。
效用与商业用途
相片dealing的效用是:可将重要信息载入相片,并可加载。
可用作:在相片中放置隐密文本、给相片做不由此可见的著作权标记,之类。
控制技术基本原理
相片,是由画素形成;画素都是由RGB(三色)原色共同组成,比如说css时用八十进制表述色调:#FFFFFF。即三色各为FF。两个FF是转成十十进制,是8bit:11111111,假如修正最终一名,是不负面影响色调和相片表明的。由此由此可见,“dealing”会即将暗藏的重要信息,载入到这个8bit的最终一名。
比如:要C8016A字符串“a”,先转化成a为2十进制:”a”.charCodeAt(0).toString(2)
获得值:”01100001″,C8016A会展开如下表所示操作方式:
用程序同时实现时,流程为:
1、读取原图,获得图的画素级bit重要信息;
2、即将C8016A的重要信息,转成2十进制;
3、将十十进制的C8016A重要信息,载入到每个画素最终一名;
4、保存,生成新相片。
。
源码解析
以上介绍了控制技术基本原理,接下来,编程同时实现。先对源码功能做介绍,最终将给出完整的功能源码。
本例程源码,将在两个html文件中同时实现,有html代码和JavaScript代码两部分共同组成。
Html部分
html代码有两个共同组成部分:加载相片并C8016A文本、从C8016A相片加载重要信息。
JavaScript部分
初始化时,给相片文件加载、C8016A重要信息按钮、加载重要信息按钮等页面元素绑定操作方式函数:
选择相片后,表明在画布中:
将重要信息C8016A到相片中:
核心代码:C8016A操作方式:
C8016A时,将重要信息转成十十进制并保存到相片各画素最低位。
前面是C8016A部分,接下来,是从C8016A相片中加载重要信息:
C8016A时,是将重要信息转成十十进制,此时是逆操作方式:
以上即是全部功能代码。总计不到200行,同时实现了完整的C8016A和加载。
实际应用时,C8016A部分和加载重要信息部分,应该是独立、分离使用的。
为了防止加载逻辑被他人分析识破,可以对加载C8016A的功能代码做保护。
比如说对上面这部分JS代码,使用JShaman展开混淆加密:
JS代码“C8016A”
在JShaman平台,对代码保护:
生成加密的代码:
再复制回原位置:
这样JS代码将不能被分析,而运行不受负面影响。
运行效用
完整源码
最终,附上完整源码,保存为html文件即可使用。
选择文件:
相片预览:
C8016A重要信息:
C8016A
C8016A相片:
从C8016A相片加载重要信息
读出的C8016A文本:
window.onload = function() {var input = document.getElementById(file);input.addEventListener(change, importImage);var encodeButton = document.getElementById(encode);encodeButton.addEventListener(click, encode);var decodeButton = document.getElementById(decode);decodeButton.addEventListener(click, decode);};var importImage = function(e) {var reader = new FileReader();reader.onload = function(event) {var img = new Image();img.onload = function() {var ctx = document.getElementById(canvas).getContext(2d);ctx.canvas.width = img.width;ctx.canvas.height = img.height;ctx.drawImage(img, 0, 0);};img.src = event.target.result;};reader.readAsDataURL(e.target.files[0]);};//C8016A并保存相片var encode = function() {//重要信息var message = document.getElementById(message).value;//C8016A后的相片var output = document.getElementById(output);//画布var canvas = document.getElementById(canvas);var ctx = canvas.getContext(2d);console.log(message)//是否超过能C8016A的最大量var pixelCount = ctx.canvas.width * ctx.canvas.height;if ((message.length + 1) * 16 > pixelCount * 4 * 0.75) {alert(文本太多了,超过了可载入的最大量);return;}//核心函数:C8016Avar imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);encodeMessage(imgData.data, message);ctx.putImageData(imgData, 0, 0);alert(C8016A成功,重要信息已暗藏到相片中);//表明出C8016A后的相片output.src = canvas.toDataURL();};//读出C8016A的重要信息var decode = function() {var ctx = document.getElementById(canvas).getContext(2d);var imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);//核心功能:从相片数据中加载C8016A重要信息var message = decodeMessage(imgData.data);alert(message)document.getElementById(messageDecoded).innerHTML = message;};//将十十进制编码重要信息转成字符串串var getNumberFromBits = function(bytes, history) {var number = 0, pos = 0;while (pos < 16) {var loc = getNextLocation(history, bytes.length);var bit = getBit(bytes[loc], 0);number = setBit(number, pos, bit);pos++;}return number;};var getNextLocation = function(history, total) {var pos = history.length;var loc = Math.abs(pos + 1) % total;while (true) {if (loc >= total) {loc = 0;} else if (history.indexOf(loc) >= 0) {loc++;} else if ((loc + 1) % 4 === 0) {loc++;} else {history.push(loc);return loc;}}};var setBit = function(number, location, bit) {return (number & ~(1 << location)) | (bit << location);};//将重要信息字符串串转成十十进制编码var getMessageBits = function(message) {var messageBits = [];for (var i = 0; i < message.length; i++) {var code = message.charCodeAt(i);messageBits = messageBits.concat(getBitsFromNumber(code));}return messageBits;};var getBitsFromNumber = function(number) {var bits = [];for (var i = 0; i < 16; i++) {bits.push(getBit(number, i));}return bits;};var getBit = function(number, location) {return ((number >> location) & 1);};var encodeMessage = function(colors, message) {var messageBits = getBitsFromNumber(message.length);messageBits = messageBits.concat(getMessageBits(message));var history = [];var pos = 0;while (pos < messageBits.length) {var loc = getNextLocation(history, colors.length);colors[loc] = setBit(colors[loc], 0, messageBits[pos]);while ((loc + 1) % 4 !== 0) {loc++;}colors[loc] = 255;pos++;}};var decodeMessage = function(colors) {/*Obfuscated by JShaman.com*/var _0x265a=[length,push,fromCharCode,join];var _0x1c66=function(_0x265a55,_0x1c6643){_0x265a55=_0x265a55-0x0;var _0x2081ad=_0x265a[_0x265a55];return _0x2081ad;};var _0x2ad986=function(_0x5d3dbb,_0x36e20f,_0x4c778b,_0x1e11f6,_0x377eb9){return _0x1c66(_0x1e11f6- -0x169,_0x4c778b);};var _0xeb9032=function(_0x1ff9d9,_0x7ca6ec,_0x5d43c2,_0xaf192e,_0x146982){return _0x1c66(_0xaf192e- -0x169,_0x5d43c2);};var _0x4e4429=function(_0x1099e4,_0x3d47d8,_0x9623bb,_0x8f809f,_0x2632e4){return _0x1c66(_0x8f809f- -0x169,_0x9623bb);};var _0x3ab227=function(_0xe7a97,_0x3e4f1d,_0x3dc243,_0x7d20c1,_0x541a1b){return _0x1c66(_0x7d20c1- -0x169,_0x3dc243);};var history=[];var messageSize=getNumberFromBits(colors,history);if((messageSize+0x1)*0x10>colors[_0x2ad986(-0x167,-0x169,-0x168,-0x169,-0x16a)]*0.75){return;}var message=[];for(var i=0x0;i