⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lsbdecrypt.cs

📁 基于LSB算法的信息隐藏技术。
💻 CS
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace LSB_Algorithm
{
    class LSBDecrypt
    {
        //伪装图片的路径
        private string _camouflagePicPath = null;
        //还原出的隐藏信息的保存路径
        private string _infoSavePath = null;
        //伪装图片的文件流
        private FileStream _camouflageStream = null;
        //还原出的隐藏信息的文件流
        private FileStream _infoSaveStream = null;

        /// <summary>
        /// LSBDecrypt的构造函数
        /// </summary>
        /// <param name="path1">伪装图片的路径</param>
        /// <param name="path2">还原出的隐藏信息的保存路径</param>
        public LSBDecrypt(string path1, string path2)
        {
            _camouflagePicPath = path1;
            _infoSavePath = path2;
        }

        /// <summary>
        /// 从伪装图片的第55至第66字节中提取出隐藏信息的长度
        /// </summary>
        /// <returns>隐藏信息长度</returns>
        private int GetInfoLength()
        {
            _camouflageStream = new FileStream(_camouflagePicPath, FileMode.Open, FileAccess.Read);
            //将文件流定位到第55个字节处
            _camouflageStream.Position = 54;
            //读取包含隐藏信息长度的12个字节块
            byte[] lengthBlock = new byte[12];
            _camouflageStream.Read(lengthBlock, 0, lengthBlock.Length);
            //提取LSB
            byte[] lengthBitArray = ExtractHidingBits(lengthBlock);
            //还原出整型长度值
            int len = lengthBitArray[0] * 65536 + lengthBitArray[1] * 256 + lengthBitArray[2];
            //如果长度不正确表明该图片不含有隐藏信息,此检测LSB方法不能适用于所有情况,具体的检测算法未知
            if (len <=0 || len > (_camouflageStream.Length - 54) / 4 - 3)
            {
                _camouflageStream.Close();
                return -1;
            }
            return len;
        }

        /// <summary>
        /// 利用位操作提取伪装文件流中每12字节的LSB位
        /// </summary>
        /// <param name="arr">长度为12的字节数组,含有隐藏信息</param>
        /// <returns>从12字节块中提取出的3字节隐藏信息</returns>
        private byte[] ExtractHidingBits(byte[] arr)
        {
            //用于存放从12个字节块中提取出来的3个字节的隐藏信息
            byte[] buf = new byte[3];
            //24个bit位的处理
            buf[0] = (byte)((arr[0] & 2) == 0 ? (buf[0] & 127) : (buf[0] | 128));           //a7
            buf[0] = (byte)((arr[0] & 1) == 0 ? (buf[0] & 191) : (buf[0] | 64));            //a6
            buf[0] = (byte)((arr[1] & 1) == 0 ? (buf[0] & 223) : (buf[0] | 32));            //a5
            buf[0] = (byte)((arr[2] & 4) == 0 ? (buf[0] & 239) : (buf[0] | 16));            //a4
            buf[0] = (byte)((arr[2] & 2) == 0 ? (buf[0] & 247) : (buf[0] | 8));             //a3
            buf[0] = (byte)((arr[2] & 1) == 0 ? (buf[0] & 251) : (buf[0] | 4));             //a2
            buf[0] = (byte)((arr[3] & 2) == 0 ? (buf[0] & 253) : (buf[0] | 2));             //a1
            buf[0] = (byte)((arr[3] & 1) == 0 ? (buf[0] & 254) : (buf[0] | 1));             //a0

            buf[1] = (byte)((arr[4] & 1) == 0 ? (buf[1] & 127) : (buf[1] | 128));           //b7
            buf[1] = (byte)((arr[5] & 4) == 0 ? (buf[1] & 191) : (buf[1] | 64));            //b6
            buf[1] = (byte)((arr[5] & 2) == 0 ? (buf[1] & 223) : (buf[1] | 32));            //b5
            buf[1] = (byte)((arr[5] & 1) == 0 ? (buf[1] & 239) : (buf[1] | 16));            //b4
            buf[1] = (byte)((arr[6] & 2) == 0 ? (buf[1] & 247) : (buf[1] | 8));             //b3
            buf[1] = (byte)((arr[6] & 1) == 0 ? (buf[1] & 251) : (buf[1] | 4));             //b2
            buf[1] = (byte)((arr[7] & 1) == 0 ? (buf[1] & 253) : (buf[1] | 2));             //b1
            buf[1] = (byte)((arr[8] & 4) == 0 ? (buf[1] & 254) : (buf[1] | 1));             //b0
            
            buf[2] = (byte)((arr[8] & 2) == 0 ? (buf[2] & 127) : (buf[2] | 128));           //c7
            buf[2] = (byte)((arr[8] & 1) == 0 ? (buf[2] & 191) : (buf[2] | 64));            //c6
            buf[2] = (byte)((arr[9] & 2) == 0 ? (buf[2] & 223) : (buf[2] | 32));            //c5
            buf[2] = (byte)((arr[9] & 1) == 0 ? (buf[2] & 239) : (buf[2] | 16));            //c4
            buf[2] = (byte)((arr[10] & 1) == 0 ? (buf[2] & 247) : (buf[2] | 8));            //c3
            buf[2] = (byte)((arr[11] & 4) == 0 ? (buf[2] & 251) : (buf[2] | 4));            //c2
            buf[2] = (byte)((arr[11] & 2) == 0 ? (buf[2] & 253) : (buf[2] | 2));            //c1
            buf[2] = (byte)((arr[11] & 1) == 0 ? (buf[2] & 254) : (buf[2] | 1));            //c0

            return buf;
        }

        /// <summary>
        /// 执行信息提取操作
        /// </summary>
        /// <returns>执行成功返回true,失败返回false</returns>
        public bool ExecuteDecrypt()
        {
            int infoLen = GetInfoLength();
            if (infoLen == -1)
            {
                return false;
            }
            _infoSaveStream = new FileStream(_infoSavePath, FileMode.Create, FileAccess.Write);
            //置文件流位置
            _camouflageStream.Position = 66;
            _infoSaveStream.Position = 0;
            //计算循环次数
            int cycle = (infoLen % 3 == 0) ? (infoLen / 3) : (infoLen / 3 + 1);
            //按12字节一组每次提取3个字节的隐藏信息并写入文件
            for (int i = 0; i < cycle; i++)
            {
                byte[] contentBlock = new byte[12];
                _camouflageStream.Read(contentBlock, 0, contentBlock.Length);
                byte[] contentBitArray = ExtractHidingBits(contentBlock);
                _infoSaveStream.Write(contentBitArray, 0, contentBitArray.Length);
            }
            _infoSaveStream.Flush();
            _camouflageStream.Close();
            _infoSaveStream.Close();
            return true;
        }
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -