2024蓝桥杯网络安全-图片隐写-缺失的数据(0基础也能学会-含代码解释)

解压给的压缩包,可以看到有三个内容

image-20240428112135187

解压这个压缩包可以得到一个txt文件,查看里面你的内容像是一个字典

image-20240428112232231

我们尝试使用ARCHPR中的字典模式爆破压缩包

image-20240428112423071

后缀改为dic,方便后面查找到

image-20240428112505265

点击打开添加要暴力破解的文件,攻击方式选择字典,字典选择刚才改好的文件-secret.dic,点击开始爆破,这里记得清除掉开始行,爆破完成后,可以看到密码

image-20240428112710610

pavilion就是密码,解压压缩包,可以得到一张图片-a.png

a

对比另外给出的一张图片newlmg.png

newImg

查看给出的代码,有加水印也有解水印代码,我们可以知道需要进行仿写

image-20240428113321369

纯小白没有安装这两个库,安装cv2会报错,我们安装opencv-python

image-20240428113405098

image-20240428113830680

直接安装pywt库是会报错的,我们win+r 进入界面中 执行--pip install PyWavelets--即可安装成功,当然我们也可以直接在pycharm中安装

搜索PyWavelets安装即可,我的电脑里有3.10和3.12两个版本的python,因为3.12不支持ida,所以指定了默认的python为3.10,这也就导致了使用命令行的方式安装python包都会安装到3.10下面,而换用3.12的环境就会报错。所以在修改了安装库的源后(这样安装更快)直接在pycharm中搜索安装即可。

image-20240428123202276

安装完成后可以通过以下路径找到安装的包,注意安装成功后会有两个包,一个图中标的,一个是pywt

image-20240428114606011

代码可以直接拿过来用,将刚才得到的两张照片,粘贴到pycharm中和代码的一个目录下,就可以执行出结果

image-20240428123500204

执行的结果

image-20240428123522838

代码分析学习

import cv2
import numpy as np
import pywt
'''
该函数是一个类的构造函数,用于初始化图像水印对象。
函数参数包括原始图像路径origin,水印图像路径watermark,密钥key和权重列表weight。
函数内部通过cv2.imread()函数读取原始图像和水印图像,并将它们分别保存在self.img和self.mark属性中。
另外,将密钥保存在self.key属性中,权重列表保存在self.coef属性中。
'''
​
class WaterMarkDWT:
    def __init__(self, origin: str, watermark: str, key: int, weight: list):
        self.key = key
        self.img = cv2.imread(origin)
        self.mark = cv2.imread(watermark)
        self.coef = weight
​
        
 '''
 该函数名为arnold,接受一个参数img,返回一个经过Arnold变换后的图像。
首先,获取输入图像img的行数和列数,分别赋值给变量r和c。
创建一个与输入图像img大小相同的全零数组p,用于存储变换后的图像。
初始化变换参数a和b为1。
使用三层嵌套循环对输入图像的每个像素进行变换:
外层循环控制变换次数,共进行self.key次变换。
中层循环遍历输入图像的每一行。
内层循环遍历输入图像的每一列。
在每次变换中,根据变换公式计算出变换后的像素坐标x和y:
x = (i + b * j) % r
y = (a * i + (a * b + 1) * j) % c
将变换前的像素值赋给变换后的像素位置p[x, y]。
循环结束后,返回变换后的图像p。
该函数的作用是对输入图像进行Arnold变换,变换次数由self.key决定。Arnold变换是一种常见的图像处理技术,可用于图像加密、图像混淆等应用场景。
 '''       
    def arnold(self, img):
        r, c = img.shape
        p = np.zeros((r, c), np.uint8)
​
        a, b = 1, 1
        for k in range(self.key):
            for i in range(r):
                for j in range(c):
                    x = (i + b * j) % r
                    y = (a * i + (a * b + 1) * j) % c
                    p[x, y] = img[i, j]
        return p
​
    '''
    该函数用于对输入的图像进行Arnold变换。Arnold变换是一种对图像进行扭曲变形的算法。函数通过遍历输入图像的每个像素,并根据一定的计算公式计算出变换后的像素位置,并将对应像素值保存在结果图像中。返回变换后的图像。其中,self.key表示变换次数。
    '''
    def deArnold(self, img):
        r, c = img.shape
        p = np.zeros((r, c), np.uint8)
​
        a, b = 1, 1
        for k in range(self.key):
            for i in range(r):
                for j in range(c):
                    x = ((a * b + 1) * i - b * j) % r
                    y = (-a * i + j) % c
                    p[x, y] = img[i, j]
        return p
​
    
   '''
   该函数是一个图像处理函数,主要实现了以下功能:
图像缩放:使用cv2.resize函数将输入图像按照指定的大小进行缩放。
图像颜色空间转换:使用cv2.cvtColor函数将输入图像和标记图像从RGB颜色空间转换为灰度颜色空间。
小波分析:使用pywt.wavedec2函数对标记图像和输入图像进行小波分解,得到小波系数。
系数调整:根据给定的系数,计算出标记图像和输入图像的小波系数之差,并进行调整。
小波重构:使用pywt.waverec2函数将调整后的小波系数重构为图像。
Arnold变换:对重构后的图像进行Arnold变换,增加图像的随机性。
膨胀和腐蚀操作:根据输入的标志flag,选择对图像进行膨胀或腐蚀操作。
返回处理后的图像。
函数的输入参数包括图像的大小size、标志flag,以及一些内部使用的系数
   
   ''' 
    
    def get(self, size: tuple = (1200, 1200), flag: int = None):
        img = cv2.resize(self.img, size)
​
        img1 = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        img2 = cv2.cvtColor(self.mark, cv2.COLOR_RGB2GRAY)
​
        c = pywt.wavedec2(img2, 'db2', level=3)
        [cl, (cH3, cV3, cD3), (cH2, cV2, cD2), (cH1, cV1, cD1)] = c
​
        d = pywt.wavedec2(img1, 'db2', level=3)
        [dl, (dH3, dV3, dD3), (dH2, dV2, dD2), (dH1, dV1, dD1)] = d
​
        a1, a2, a3, a4 = self.coef
​
        ca1 = (cl - dl) * a1
        ch1 = (cH3 - dH3) * a2
        cv1 = (cV3 - dV3) * a3
        cd1 = (cD3 - dD3) * a4
​
        # Ensure all coefficients have the same shape
        ca1 = cv2.resize(ca1, (cD3.shape[1], cD3.shape[0]))
​
        waterImg = pywt.waverec2([ca1, (ch1, cv1, cd1)], 'db2')
        waterImg = np.array(waterImg, np.uint8)
​
        waterImg = self.deArnold(waterImg)
​
        kernel = np.ones((3, 3), np.uint8)
        if flag == 0:
            waterImg = cv2.erode(waterImg, kernel)
        elif flag == 1:
            waterImg = cv2.dilate(waterImg, kernel)
​
        return waterImg
​
'''
传入一些参数
'''
if __name__ == '__main__':
    img = 'a.png'
    watermark = 'newImg.png'
    
    k = 20
    xs = [0.2, 0.2, 0.5, 0.4]
    
    W1 = WaterMarkDWT(img, watermark, k, xs)
    extracted_watermark = W1.get()
    cv2.imwrite('提取出的水印.png', extracted_watermark)

相关推荐

  1. 0411代码,备战基础数据结构

    2024-05-11 09:32:08       13 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-11 09:32:08       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-11 09:32:08       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-11 09:32:08       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-11 09:32:08       20 阅读

热门阅读

  1. html的i标签 “\e905“ font-family 字体没有效果

    2024-05-11 09:32:08       10 阅读
  2. 学习Uni-app开发小程序Day7

    2024-05-11 09:32:08       8 阅读
  3. 在linux中学会安装与基本配置redis

    2024-05-11 09:32:08       11 阅读
  4. 在Ubuntu下搭建自己的以太坊私有链

    2024-05-11 09:32:08       11 阅读
  5. 使用Azure云服务部署你的第一个应用

    2024-05-11 09:32:08       10 阅读
  6. rk3588 安卓13 暴露相机开关接口

    2024-05-11 09:32:08       10 阅读