图像隐写之使用PHP隐藏图像中的文本

2019-04-01 23:23:27

隐写术是一门研究隐藏信息的科学艺术,通过隐写术,可以只让发送者和接收者知道隐藏的信息。

图像隐写术则是研究将数据隐藏在图像中,通过该技术可以防止无关用户发现这些隐藏的信息或数据。

相关的原理

图像都是由很小的点组成的,这些点就是像素。每个像素由三个字节来表示:一个代表红(Red),一个代表绿(Green),一个代表蓝(Blue)。这三种颜色的组合决定了像素的实际颜色。

红色:

二进制:11001001

十进制:201

绿色:


二进制:11111000

十进制:248(原文此处为201,实际应为248)

蓝色:

二进制:00000011

十进制:3

这一组合呈现的像素颜色是橙色。

图像隐写的基本原理就是修改LSB(Least Significant Bit,最不重要的那一bit)并不会被人眼察觉到。所以我们修改RGB的LSB值来存储隐藏信息,同时不影响图像的颜色。

在这个例子中,我们仅仅修改蓝色的LSB,但是如果我们想的话,也可以修改所有的红,绿和蓝的成分。不过只修改蓝色的LSB,我们可以隐藏的信息更少一些。我们也可以将要隐藏信息的长度存储到图像中,不过本教程中还没有做这一点。

假设我们现在要将1101藏到图片中。

首先我们要得到图片中每个像素的RGB值,因为我们要隐藏4bit的数据,而且我们要修改蓝色的部分,所以我们需要4个像素。

假设图片前4个像素的RGB值如下:

11001100 10010001 00101011

00011000 11110000 11111110

11100010 00100101 01010101

11111101 00001010 01000011

现在,我们将这4个RGB值最后的bit替换成1101,

现在新的RGB值变成了:

11001100 10010001 00101011

00011000 11110000 11111111

11100010 00100101 01010100

11111101 00001010 01000011

加粗的最后一bit,就是我们要隐藏到图片的信息。

现在将新的RGB值应用到像素,因为人眼并不会注意到这种改变,所以图片看起来还是一样的。

加密的部分到现在就完成了,接下来我们将解密隐藏在图片的信息。

为了达到这一点,我们需要取出每个像素的RGB值,然后合并LSB来得到我们隐藏的信息。

用PHP实现

我们需要一张图片和3个php脚本来实现基本的图像隐写。

encrypt.php

decrypt.php

functions.php

1.jpg


encrypt.php

include('functions.php');

$message_to_hide = 'hello';

$binary_message = toBin($message_to_hide);

$message_length = strlen($binary_message);

$src = '1.jpg';

$im = imagecreatefromjpeg($src);

for($x=0;$x<$message_length;$x++){

$y = $x;

$rgb = imagecolorat($im,$x,$y);

$r = ($rgb >>16) & 0xFF;

$g = ($rgb >>8) & 0xFF;

$b = $rgb & 0xFF;

$newR = $r;

$newG = $g;

$newB = toBin($b);

$newB[strlen($newB)-1] = $binary_message[$x];

$newB = toString($newB);

$new_color = imagecolorallocate($im,$newR,$newG,$newB);

imagesetpixel($im,$x,$y,$new_color);

}

echo $x;

imagepng($im,'simple.png');

imagedestroy($im);

?>

decrypt.php

include('functions.php');

$src = 'simple.png';

$im = imagecreatefrompng($src);

$real_message = '';

for($x=0;$x<40;$x++){

$y = $x;

$rgb = imagecolorat($im,$x,$y);

$r = ($rgb >>16) & 0xFF;

$g = ($rgb >>8) & 0xFF;

$b = $rgb & 0xFF;

$blue = toBin($b);

$real_message .= $blue[strlen($blue)-1];

}

$real_message = toString($real_message);

echo $real_message;

die;

?>


functions.php

function toBin($str){

$str = (string)$str;

$l = strlen($str);

$result = '';

while($l--){

$result = str_pad(decbin(ord($str[$l])),8,"0",STR_PAD_LEFT).$result;

}

return $result;

}

function toString($binary){

return pack('H*',base_convert($binary,2,16));

}

?>

更多的信息可以查看这个视频:

视频地址:yotube: https://youtu.be/qH0wLIwZa0U (自备梯子)


  • 2020-04-03 19:10:56

    nodejs与javascript中的aes加密

    aes加密简单来说,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。高级加密标准已然成为对称密钥加密中最流行的算法之一。

  • 2020-04-03 19:13:05

    Express-session的使用

    当浏览器访问服务器并发送第一次请求时,服务器端会创建一个 session 对象,生成一个类似于 key,value 的键值对,然后将 key(cookie)返回到浏览器(客户)端,浏览器下次再访问时,携带 key(cookie), 找到对应的 session(value)。 客户的信息都保存在 session 中

  • 2020-04-08 22:46:28

    Element的操作方法

    Element 是一个通用性非常强的基类,所有 Document 对象下的对象都继承自它。这个接口描述了所有相同种类的元素所普遍具有的方法和属性。一些接口继承自 Element 并且增加了一些额外功能的接口描述了具体的行为。例如, HTMLElement 接口是所有 HTML 元素的基本接口,而 SVGElement 接口是所有 SVG 元素的基础。大多数功能是在这个类的更深层级(hierarchy)的接口中被进一步制定的。

  • 2020-04-12 17:42:43

    Node.js设置CORS跨域请求中多域名白名单的方法

    在Node.js中,res的响应头Header中的 Access-Control-Allow-Origin 属性不能匹配除 (*) 以外的正则表达式的,域名之间不能也用逗号分隔。也就是说, Access-Control-Allow-Origin 的属性值只允许设置为单个确定域名字符串或者 (*)。

  • 2020-04-14 09:40:59

    CSS3实现文字描边的2种方法

    首先想到去看CSS3有没有什么属性可以实现,后来被我找到了text-stroke     该属性是一个复合属性,可以设置文字宽度和文字描边颜色      该属性使用很简单:text-stroke:1px #f00;(1px是文字宽度,#ff是文字描边颜色)

  • 2020-04-14 09:42:47

    用 TypeScript 编写 npm 模块

    自从开始使用 Node.js 已经一年多,写的代码越多,越是觉得自己提高的越慢。想来应该有没有将单一功能的代码封装在一个独立模块,而导致代码稍微多一点就维护困难的原因。