信息隐藏实验一 LSB隐写和RS分析实现

一、LSB隐写

1. 简介
  • 隐写对象:bmp 图像,图像内容为原始像素值
  • 隐写方式:将秘密信息转换为二进制比特流,嵌入像素值的最低位中(对图像的影响最小)
  • 隐写规则:嵌入0,将对应像素值最低位置为0;嵌入1则置为1
  • 提取方式:提取像素值最低位,重新转换为对应数据编码
2. 实现
  • 读取原始图像:图像头+图像内容,我们可以进行隐写的部分为内容部分

    void readHeader(FILE *image, UCHAR header[]) {
        fread(header, 1, 1078, image); // bmp文件头长度为1078(带调色板)
    }
    
    void readImage(FILE *image, UCHAR raw[DEGREE][DEGREE]) {
        int i; // 读取像素值,512*512
        for(i = 0; i < DEGREE; i++) fread(raw + i, sizeof(UCHAR), DEGREE, image);
    }
    
  • 嵌入秘密信息:方便起见,秘密信息为随机比特流;此处加上了嵌入率的设定

    // 嵌入率为 1/rate
    void randomCipherWrite(UCHAR raw[DEGREE][DEGREE], int rate) {
        int i, j;
        for(i = 0; i < DEGREE; i++) {
            for(j = 0; j < DEGREE; j++) {
                if(!(getCipher(1) % rate)) { // 生成随机数, 若摸rate为0则进行一次嵌入
                    if(!getCipher(0)) { // 嵌入0: 2i+1 -> 2i
                        if(raw[i][j] % 2) raw[i][j]--;
                    } else { // 嵌入1: 2i -> 2i+1
                        if(!(raw[i][j] % 2)) raw[i][j]++;
                    }
                }
            }
        }
    }
    
  • 生成嵌入秘密信息的图像,将原始 bmp 头和修改后的像素值写入文件,略

二、RS分析

1. 简介
  • 分析对象:可能进行了 LSB 隐写的 bmp 图像

  • 概念说明:

    • 正翻转: 2 i ↔ 2 i + 1 2i \leftrightarrow 2i+1 2i2i+1
    • 负翻转: 2 i ↔ 2 i − 1 2i \leftrightarrow 2i-1 2i2i1
    • 零翻转:像素值不变
    • 非负翻转:随机进行正翻转或零翻转
      • 对图像进行 LSB 隐写相当于进行了一次非负翻转
    • 非正翻转:随机进行负翻转或零翻转
    • 相关性(混乱度):将像素值矩阵进行 Z 形排序,得到像素序列,通过以下方式计算相关性

    r = ∑ ∣ x i − x i − 1 ∣ \text{r} = \sum|x_i - x_{i-1}| r=xixi1

  • 分析原理:

    • 对于原始图像,单独进行一次 非负翻转 或一次 非正翻转 ,对 r \text{r} r 的影响是相近的

    • 对于进行了一次 非负翻转 的图像,若

      • 再进行一次 非负翻转,对 r \text{r} r 的影响很小;就是来回了一遍

      • 再进行一次 非正翻转,会显著的影响 r r r;考虑下例
        2 i → 2 i + 1 = 2 ( i + 1 ) − 1 → 2 ( i + 1 ) = 2 i + 2 2i \rightarrow 2i + 1 = 2(i + 1) - 1 \rightarrow 2(i + 1) = 2i + 2 2i2i+1=2(i+1)12(i+1)=2i+2
        即像素被放大/缩小的更多了,因此像素值间的距离也会相应的增大,那么 r r r 值就会增大

  • 图像分块:

    • 为了更好的衡量进行翻转后的图像的相关形变化,将原始图像分为多个 8 × 8 8 \times 8 8×8 矩阵
    • 计算每个矩阵的相关性,可以得到一个相关性序列
    • 通过统计翻转前后相关性增加/减少的矩阵块数(比例),量化翻转带来的影响,记
      • 相关性增加的比例,记为 R m R_m Rm
      • 相关性减少的比例,记为 S m S_m Sm
  • 分析步骤:

    • 计算得到待分析图像的相关性序列
    • 对待分析图像分别进行非负、非正翻转,分别得到其对应的相关性序列
    • 统计
      • 非负翻转后,相关性增加的比例 R m + R_{m+} Rm+
      • 非正反转后,相关性增加的比例 R m − R_{m-} Rm
    • 根据上面的原理分析,可知
      • 若待分析图像为原始图像,则 R m + ≈ R m − R_{m+} \approx R_{m-} Rm+Rm
      • 若待分析图像进行了 LSB 隐写(即进行了一次非负翻转),则 R m + < R m − R_{m+} < R_{m-} Rm+<Rm
        • 且随着 LSB 嵌入率的增加,两者的差距会越来越大
2. 实现
  • 读取待分析图像,同上

  • 对待分析图像进行非负翻转(随机正翻转或零翻转)

    void pos_reverse(UCHAR pos_raw[DEGREE][DEGREE]) { // 非负翻转
        int i, j;
        for(i = 0; i < DEGREE; i++) {
            for(j = 0; j < DEGREE; j++) {
                if(!getCipher(0)) { // 进行正翻转
                    if(!getCipher(0)) { // 嵌入0: 2i+1 -> 2i
                        if(pos_raw[i][j] % 2) pos_raw[i][j]--;
                    } else { // 嵌入1: 2i -> 2i + 1
                        if(!(pos_raw[i][j] % 2)) pos_raw[i][j]++;
                    }
                } else { // 进行0翻转
                    /* empty */                
                }
            }
        }
    }
    
  • 对待分析图像进行非正翻转(随机负翻转或零反转)

    void neg_reverse(UCHAR neg_raw[DEGREE][DEGREE]) { // 非正翻转
        int i, j;
        for(i = 0; i < DEGREE; i++) {
            for(j = 0; j < DEGREE; j++) {
                if(!getCipher(0)) { // 进行负翻转
                    if(!getCipher(0)) { // 嵌入0: 2i-1 -> 2i
                        if(neg_raw[i][j] % 2) neg_raw[i][j]++;
                    } else { // 嵌入1: 2i -> 2i-1
                        if(!(neg_raw[i][j] % 2)) neg_raw[i][j]--;
                    }
                } else { // 进行0翻转
                    /* empty */
                }
            }
        }
    }
    
  • 计算待分析图像、非负翻转图像、非正翻转图像的相关性序列

    // 计算相关性序列
    void getRelevance(UCHAR raw[DEGREE][DEGREE], int relv[]) {
        
        UCHAR pixel[BLOCKD * BLOCKD] = {0}; // Z形排序后的像素值
    
        int i, j, bcnt = 0;
        for(i = 0; i < DEGREE; i += 8) { // 分块
            for(j = 0; j < DEGREE; j += 8) { // 分块
                getBlockZIndex(raw, i, j, pixel); // 得到分块矩阵的Z形排序
                relv[bcnt++] = getBlockRelevance(pixel); // 计算改矩阵的相关性
            }
        }
    }
    // 计算矩阵Z形排序
    void getBlockZIndex(UCHAR raw[DEGREE][DEGREE], int sx, int sy, UCHAR pixel[]) {
        int index = 0, x = 0, y = 0, i;
        while(index < (BLOCKD * BLOCKD + BLOCKD) / 2) {
            for(;y >= 0; x++, y--) pixel[index++] = raw[sx + x][sy + y]; y++; // 向坐下走
            for(;x >= 0; x--, y++) pixel[index++] = raw[sx + x][sy + y]; x++; // 向右上走
        }
        x++; y--;
        while(index < BLOCKD * BLOCKD) {
            for(;x < BLOCKD; x++, y--) pixel[index++] = raw[sx + x][sy + y]; x--, y+=2; // 向坐下走
            for(;y < BLOCKD; x--, y++) pixel[index++] = raw[sx + x][sy + y]; y--; x+=2; // 向右上走
        }
    }
    // 计算像素序列相关性
    int getBlockRelevance(UCHAR pixel[]) {
        int relevance = 0, i;
        for(i = 1; i < BLOCKD * BLOCKD; i++) {
            relevance += abs(pixel[i] - pixel[i - 1]);
        }
        return relevance;
    }
    
  • 比较相关性变化,计算得到 R m R_m Rm S m S_m Sm

    /*
     * @param raw_relv 待分析图像的原始相关性序列
     * @param mod_relv 翻转图像的相关性序列
     **/
    double getRm(int raw_relv[], int mod_relv[]) {
        int i, insb = 0;
        for(i = 0; i < BLOCK_CNT; i++) {
            if(raw_relv[i] < mod_relv[i]) insb++;
        }
        return insb * 1.0 / BLOCK_CNT;
    }
    
  • 输出比较 R m + R_{m+} Rm+ R m − R_{m-} Rm

3. 运行验证
  • 对原始图像分别进行嵌入率为 1,1/2,1/4,1/8,1/16,1/32的 LSB 隐写

    @echo off
    .\write .\image\lena_gray.bmp .\image\1.bmp 1
    .\write .\image\lena_gray.bmp .\image\2.bmp 2
    .\write .\image\lena_gray.bmp .\image\4.bmp 4
    .\write .\image\lena_gray.bmp .\image\8.bmp 8
    .\write .\image\lena_gray.bmp .\image\16.bmp 16
    .\write .\image\lena_gray.bmp .\image\32.bmp 32
    
  • 对原始图像及以上图像进行 RS \text{RS} RS 分析

    @echo off
    .\analysis .\image\lena_gray.bmp
    .\analysis .\image\32.bmp
    .\analysis .\image\16.bmp
    .\analysis .\image\8.bmp
    .\analysis .\image\4.bmp
    .\analysis .\image\2.bmp
    .\analysis .\image\1.bmp
    
  • 查看运行结果,可以看出,随着嵌入率的增加, R m + R_{m+} Rm+ R m − R_{m-} Rm 的差值越来越大

    在这里插入图片描述

参考源码

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值