We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
大家都知道在信息经过加密算法处理后,我们一般是无法直接从信息中读取内容,而且信息看上去并不那么合理。对于专注信息安全的人,可以从信息的奇怪的外观上判断信息是否经过加密处理,这无疑是此地无银三百两,招着人家来破解你的加密内容。
而今天要介绍的图片隐写则更像是“大隐隐于市”的一种技巧。
图片隐写正是隐写术的一种。隐写术的英文是Steganography,来源于15世纪一个德国修道士特里特米乌斯(Trithemius)写的一本讲述密码学和隐写术的著作《Steganographia》。该书书名源于希腊语,意为“隐秘书写”。
隐写术的使用可以追溯到希腊时代。当时有个人为了能够将机密信息传递给盟友,于是将一个奴隶的头发剃光,然后在头皮上写上内容,等到奴隶的头发长长后就派他去送信。盟友只需要再将这个奴隶的头发剃光即可获得信息。
隐写术不同于密码术,它更为隐蔽。密码术虽然无法让人直接获取到内容,但是在信息的传递过程中可以被一眼辨认出与正常内容的区别。而隐写术可以说是侧重在隐蔽信息的传递过程。
我们来看这张图
好像就是一张平白无奇的纯蓝色的图,是吗?其实这张图片中还隐藏了一张图。在讲述如何破解隐写内容之前,我们先聊聊是如何将另一张图片隐写入原图的。
我们知道一张图片是由许多的像素点组成的。每个像素点包含4个通道,即 R(红)G(绿)B(蓝)A(透明度),我们就从通道上做手脚。
最简单的,由于肉眼无法区分像素值上的细微差距。可能有自称像素眼的同学不信,你有看出下图的颜色区别吗?
既然我们无法区分像素值的细微差别,那么利用这点,我们就可以实现图片隐写术了。
我们看下被隐写的图片:
可以看见这张图中的颜色并不是很丰富,大约只有三种颜色。那么我们通过 PS 取色,可以获得如下三个颜色:
rgba(29, 122, 217, 255) rgba(255, 255, 255, 255) rgba(255, 111, 0, 255)
imageData
然后将原图像素的红通道的个位数拍扁(置 0),这里以 canvas 获取的 imageData 对象为例:
// 循环原图的 imageData.data for (i; i < l; i += 4) { imgData[i + 0] = (imgData[i + 0] / 10 | 0) * 10 }
由于取色器获取的颜色与被隐的图像上的颜色会有细微差别,所以设置一个阈值做容差处理。在循环原图像素的同时,获取被隐图像上对应点的像素值,进行比对:
for (i; i < l; i += 4) { if ( Math.abs(simgData[i + 0] - 29) < yu && Math.abs(simgData[i + 1] - 122) < yu && Math.abs(simgData[i + 2] - 217) < yu ) { imgData[i + 0] = (imgData[i + 0] / 10 | 0) * 10 } else if ( Math.abs(simgData[i + 0] - 255) < yu && Math.abs(simgData[i + 1] - 255) < yu && Math.abs(simgData[i + 2] - 255) < yu ) { imgData[i + 0] = (imgData[i + 0] / 10 | 0) * 10 + 1 } else if ( Math.abs(simgData[i + 0] - 255) < yu && Math.abs(simgData[i + 1] - 111) < yu && Math.abs(simgData[i + 2] - 0) < yu ) { imgData[i + 0] = (imgData[i + 0] / 10 | 0) * 10 + 2 } else { imgData[i + 0] = (imgData[i + 0] / 10 | 0) * 10 + 3 } }
我们在代码中将被隐图像的颜色对应为原图红通道中的个位数数值:
我们的图片隐写术就这么完成了。最后产生的就是上面看着像纯蓝色的图像。
可以看出,隐写图片的关键是提取被隐图片的颜色值,然后通过一些方法将颜色值放入原图的通道数值中。上面的例子中将红通道的个位数置 0 后,可以隐入 10 中色彩的图片,如果隐入的图片色彩更丰富,可能动用更多的通道,或者通过其他的一些算法达到目的。
接下来的工作就是来进行对被隐图片的提取了。首先将上一部生成的图像数据进行循环,然后取出每个像素的红通道数值。
for (i; i < l; i += 4) { temp = imgData[i + 0] % 10 if (temp === 0) { simgData[i + 0] = 29 simgData[i + 1] = 122 simgData[i + 2] = 217 } else if (temp === 1) { simgData[i + 0] = 255 simgData[i + 1] = 255 simgData[i + 2] = 255 } else if (temp === 2) { simgData[i + 0] = 255 simgData[i + 1] = 111 simgData[i + 2] = 0 } else { simgData[i + 0] = 29 simgData[i + 1] = 122 simgData[i + 2] = 217 } }
最后我们将获得的像素数据展示出来:
好像有点失真,不过没关系,图像中的主要信息并没有丢失,我们可以清晰的看到图像中的字样。
通常我们会将自己产品的图片加上水印,以注明图片来源并避免被他人用于营利性目的。但是由于加上水印后可能会对图片产生副作用。比如遮挡了图片中信息、水印本身的美感等问题,可能会对用户造成一定的心里落差,毕竟这不是用户的原图。
而通过将产品 logo 隐写入原图的方式,就显得更加优雅,即满足了用户对上传图像的期望,又确保了在被其他商业产品盗用图片时的维权手段。
http://www.guokr.com/article/3741/
The text was updated successfully, but these errors were encountered:
打个广告:https://github.com/zcyzcy88/Polytor
Sorry, something went wrong.
@zcyzcy88 有点意思
赞
No branches or pull requests
认识图片隐写
大家都知道在信息经过加密算法处理后,我们一般是无法直接从信息中读取内容,而且信息看上去并不那么合理。对于专注信息安全的人,可以从信息的奇怪的外观上判断信息是否经过加密处理,这无疑是此地无银三百两,招着人家来破解你的加密内容。
而今天要介绍的图片隐写则更像是“大隐隐于市”的一种技巧。
## 隐写术
图片隐写正是隐写术的一种。隐写术的英文是Steganography,来源于15世纪一个德国修道士特里特米乌斯(Trithemius)写的一本讲述密码学和隐写术的著作《Steganographia》。该书书名源于希腊语,意为“隐秘书写”。
隐写术的使用可以追溯到希腊时代。当时有个人为了能够将机密信息传递给盟友,于是将一个奴隶的头发剃光,然后在头皮上写上内容,等到奴隶的头发长长后就派他去送信。盟友只需要再将这个奴隶的头发剃光即可获得信息。
隐写术不同于密码术,它更为隐蔽。密码术虽然无法让人直接获取到内容,但是在信息的传递过程中可以被一眼辨认出与正常内容的区别。而隐写术可以说是侧重在隐蔽信息的传递过程。
## 图片的隐写
我们来看这张图
有兴趣的同学可以保存图像后面会用到这张图
好像就是一张平白无奇的纯蓝色的图,是吗?其实这张图片中还隐藏了一张图。在讲述如何破解隐写内容之前,我们先聊聊是如何将另一张图片隐写入原图的。
像素通道
我们知道一张图片是由许多的像素点组成的。每个像素点包含4个通道,即 R(红)G(绿)B(蓝)A(透明度),我们就从通道上做手脚。
最简单的,由于肉眼无法区分像素值上的细微差距。可能有自称像素眼的同学不信,你有看出下图的颜色区别吗?
可以下载后用 PS 取色看看
既然我们无法区分像素值的细微差别,那么利用这点,我们就可以实现图片隐写术了。
我们看下被隐写的图片:
logo 大法好
可以看见这张图中的颜色并不是很丰富,大约只有三种颜色。那么我们通过 PS 取色,可以获得如下三个颜色:
PS 里面透明度是 0 -100%, 对应
imageData
中的数值 为 0 到 255然后将原图像素的红通道的个位数拍扁(置 0),这里以 canvas 获取的
imageData
对象为例:由于取色器获取的颜色与被隐的图像上的颜色会有细微差别,所以设置一个阈值做容差处理。在循环原图像素的同时,获取被隐图像上对应点的像素值,进行比对:
我们在代码中将被隐图像的颜色对应为原图红通道中的个位数数值:
我们的图片隐写术就这么完成了。最后产生的就是上面看着像纯蓝色的图像。
可以看出,隐写图片的关键是提取被隐图片的颜色值,然后通过一些方法将颜色值放入原图的通道数值中。上面的例子中将红通道的个位数置 0 后,可以隐入 10 中色彩的图片,如果隐入的图片色彩更丰富,可能动用更多的通道,或者通过其他的一些算法达到目的。
### 提取被隐图片
接下来的工作就是来进行对被隐图片的提取了。首先将上一部生成的图像数据进行循环,然后取出每个像素的红通道数值。
最后我们将获得的像素数据展示出来:
好像有点失真,不过没关系,图像中的主要信息并没有丢失,我们可以清晰的看到图像中的字样。
## 商业用途
通常我们会将自己产品的图片加上水印,以注明图片来源并避免被他人用于营利性目的。但是由于加上水印后可能会对图片产生副作用。比如遮挡了图片中信息、水印本身的美感等问题,可能会对用户造成一定的心里落差,毕竟这不是用户的原图。
而通过将产品 logo 隐写入原图的方式,就显得更加优雅,即满足了用户对上传图像的期望,又确保了在被其他商业产品盗用图片时的维权手段。
查看DEMO
## 参考文章
http://www.guokr.com/article/3741/
## Thanks
The text was updated successfully, but these errors were encountered: