【每周一坑】图像的指纹:数字水印 + 【解答】鸡兔同笼
曾经有过这样的新闻:某公司的员工将内网论坛上的言论截屏发布到互联网上,引发了热议。于是公司通过截图定位到了员工的身份,将其开除。
有人可能好奇,仅凭截图就能知道是谁干的吗?这里就是用到了“数字水印”技术。
数字水印(Digital Watermarking)技术是将一些标识信息(即数字水印)直接嵌入数字载体当中(包括多媒体、文档、软件等)或是间接表示(修改特定区域的结构),且不影响原载体的使用价值,也不容易被探知和再次修改。但可以被生产方识别和辨认。
— 百度百科
只要在你看的页面上嵌入了肉眼不可见的信息,记录你的身份,之后再通过相应的解码软件从流出的截屏上提取出这些信息,就能知道你是谁了。
数字水印的应用还包括防伪、防篡改、保护版权等场景。
数字水印是个很大的范畴,有很多实现方式,具有不同的实现难度、信息容量、抗攻击性、对原图的干扰等。
这里我们介绍一种很简单的实现方式:
图像中的每个像素通常可以用 RGB(红绿蓝)三个 0~255 的值来表示。如果把这个值转成二进制来表示,就是 00000000~11111111。
把每个值的最后1位全部设成0,对图像的影响非常细微,人眼无法察觉。
这样,空出来的最后1位就可以拿来存储信息。把水印字符转成二进制,依次填入这些位置上,就完成了信息的嵌入。
提取信息就是上述的逆过程:把图像的像素信息取出来,提取最后1位,拼出信息。
今天我们的题目就是:请将一段文字嵌入到一张图片中,然后再成功地复原出来。
示例原图:
嵌入信息后:
提取信息:
相比较之前的题目,这期的问题难道稍高,因此再给一些提示:
之前几次图像处理用到的 PIL 库,可以方便得到图像的像素值,以及保存新图像。
将一个字符 c 转成二进制表示:
bin(ord(c))[2:]
,反之:chr(int(s, 2))
将一个整数 x 的二进制末位设为 0:
x // 2 * 2
处理后的图像需要保存成 png 或 bmp,因为 jpg 是有损压缩,无法保证像素值不变。
仍然没有头绪的话,可以网上搜索“python 数字水印”寻找参考
详细解答和参考代码将在下次栏目中给出,也可以其他同学在留言中的代码
期待各位同学提交解答。
提交代码可以使用 paste.ubuntu.com 或
codeshare.io 等代码分享网站,只需将代码复制上去保存,即可获得一个分享地址,非常方便。