using System;
using System.Collections.Generic;
using System.Text;
using System.IO;namespace LSB_Algorithm
{
class LSBEncrypt
{
//原始图片路径
private string _originalPicPath = null;
//隐藏信息路径
private string _hidingInfoPath = null;
//原始图片的文件流
private FileStream _picStream = null;
//隐藏信息的文件流
private FileStream _infoStream = null; /// <summary>
/// LSBEncrypt类的构造函数
/// </summary>
/// <param name="path1">原始图片路径</param>
/// <param name="path2">隐藏信息的路径</param>
public LSBEncrypt(string path1, string path2)
{
_originalPicPath = path1;
_hidingInfoPath = path2;
} /// <summary>
/// 将长整型数转换为24位二进制表示的字节数组
/// </summary>
/// <param name="x">要转换的长整型数,这个数的大小不会超过2的24次方</param>
/// <returns>二进制表示的字节数组</returns>
private byte[] ConvertToBinaryArray(long x)
{
byte[] binaryArray = new byte[24];
for (int i = 0; i != 23; i++)
{
binaryArray[23 - i] = (byte)(x & 1);
x = x >> 1;
}
return binaryArray;
} /// <summary>
/// 将3个字节的字节数组转换为24位(8bit * 3)二进制表示的字节数组
/// </summary>
/// <param name="array">长度为3的字节数组</param>
/// <returns>二进制表示的字节数组</returns>
private byte[] ConvertToBinaryArray(byte[] array)
{
byte[] binaryArray = new byte[24];
int a = array[0];
int b = array[1];
int c = array[2];
for (int i = 0; i != 8; i++)
{
binaryArray[7 - i] = (byte)(a & 1);
a = a >> 1;
}
for (int i = 0; i != 8; i++)
{
binaryArray[15 - i] = (byte)(b & 1);
b = b >> 1;
}
for (int i = 0; i != 8; i++)
{
binaryArray[23 - i] = (byte)(c & 1);
c = c >> 1;
}
return binaryArray;
} /// <summary>
/// 将图像的第55至第66字节的LSB替换为隐藏信息文件的长度
/// </summary>
private void HideInfoLength()
{
byte[] picBlock = new byte[12];
//读取原始图像的第55至第66字节的内容块
_picStream.pPosition = 54;
_picStream.Read(picBlock, 0, picBlock.Length);
byte[] lenArray = ConvertToBinaryArray(_infoStream.Length);
//置入隐藏文件的长度信息
int index = 0;
for (int i = 0; i < 4; i++)
{
//置a7,a6位
picBlock[i * 3] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3] & 253) : (picBlock[i * 3] | 2));
picBlock[i * 3] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3] & 254) : (picBlock[i * 3] | 1));
//置a5位
picBlock[i * 3 + 1] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3 + 1] & 254) : (picBlock[i * 3 + 1] | 1));
//置a4,a3,a2位
picBlock[i * 3 + 2] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3 + 2] & 251) : (picBlock[i * 3 + 2] | 4));
picBlock[i * 3 + 2] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3 + 2] & 253) : (picBlock[i * 3 + 2] | 2));
picBlock[i * 3 + 2] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3 + 2] & 254) : (picBlock[i * 3 + 2] | 1));
}
//将原始文件流重定位到第55字节处并将已嵌入长度信息的12字节块写回
_picStream.Position = 54;
_picStream.Write(picBlock, 0, picBlock.Length);
_picStream.Flush();
} /// <summary>
/// 将隐藏信息以每3个字节写入原始图像从第67字节开始的每12字节块的LSB中
/// </summary>
private void HideInfoContent()
{
int readCnt = 0;
//计算循环处理的次数
long infoLen = _infoStream.Length;
int cnt = (int)(infoLen % 3 == 0 ? infoLen / 3 : infoLen / 3 + 1);
_picStream.Position = 66;
for (int i = 0; i < cnt; i++)
{
//每次循环读取BMP图像的下一个12字节的内容
byte[] picBlock = new byte[12];
readCnt = _picStream.Read(picBlock, 0, picBlock.Length);
//读取待隐藏信息的下一个3字节内容
byte[] readBuffer = new byte[3];
_infoStream.Read(readBuffer, 0, readBuffer.Length);
byte[] infoBlock = ConvertToBinaryArray(readBuffer);
//置位操作
int index = 0;
for (int ii = 0; ii < 4; ii++)
{
//置a7,a6位
picBlock[ii * 3] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3] & 253) : (picBlock[ii * 3] | 2));
picBlock[ii * 3] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3] & 254) : (picBlock[ii * 3] | 1));
//置a5位
picBlock[ii * 3 + 1] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 1] & 254) : (picBlock[ii * 3 + 1] | 1));
//置a4,a3,a2位
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 251) : (picBlock[ii * 3 + 2] | 4));
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 253) : (picBlock[ii * 3 + 2] | 2));
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 254) : (picBlock[ii * 3 + 2] | 1));
}
_picStream.Position -= readCnt;
_picStream.Write(picBlock, 0, picBlock.Length);
}
_picStream.Flush();
} /// <summary>
/// 执行信息隐藏操作
/// </summary>
public void ExecuteEncrypt()
{
_picStream = new FileStream(_originalPicPath, FileMode.Open, FileAccess.ReadWrite);
_infoStream = new FileStream(_hidingInfoPath, FileMode.Open, FileAccess.Read);
HideInfoLength();
HideInfoContent();
_picStream.Close();
_infoStream.Close();
}
}
}请教下面代码什么意思?
//置a7,a6位
picBlock[ii * 3] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3] & 253) : (picBlock[ii * 3] | 2));
picBlock[ii * 3] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3] & 254) : (picBlock[ii * 3] | 1));
//置a5位
picBlock[ii * 3 + 1] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 1] & 254) : (picBlock[ii * 3 + 1] | 1));
//置a4,a3,a2位
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 251) : (picBlock[ii * 3 + 2] | 4));
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 253) : (picBlock[ii * 3 + 2] | 2));
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 254) : (picBlock[ii * 3 + 2] | 1));
using System.Collections.Generic;
using System.Text;
using System.IO;namespace LSB_Algorithm
{
class LSBEncrypt
{
//原始图片路径
private string _originalPicPath = null;
//隐藏信息路径
private string _hidingInfoPath = null;
//原始图片的文件流
private FileStream _picStream = null;
//隐藏信息的文件流
private FileStream _infoStream = null; /// <summary>
/// LSBEncrypt类的构造函数
/// </summary>
/// <param name="path1">原始图片路径</param>
/// <param name="path2">隐藏信息的路径</param>
public LSBEncrypt(string path1, string path2)
{
_originalPicPath = path1;
_hidingInfoPath = path2;
} /// <summary>
/// 将长整型数转换为24位二进制表示的字节数组
/// </summary>
/// <param name="x">要转换的长整型数,这个数的大小不会超过2的24次方</param>
/// <returns>二进制表示的字节数组</returns>
private byte[] ConvertToBinaryArray(long x)
{
byte[] binaryArray = new byte[24];
for (int i = 0; i != 23; i++)
{
binaryArray[23 - i] = (byte)(x & 1);
x = x >> 1;
}
return binaryArray;
} /// <summary>
/// 将3个字节的字节数组转换为24位(8bit * 3)二进制表示的字节数组
/// </summary>
/// <param name="array">长度为3的字节数组</param>
/// <returns>二进制表示的字节数组</returns>
private byte[] ConvertToBinaryArray(byte[] array)
{
byte[] binaryArray = new byte[24];
int a = array[0];
int b = array[1];
int c = array[2];
for (int i = 0; i != 8; i++)
{
binaryArray[7 - i] = (byte)(a & 1);
a = a >> 1;
}
for (int i = 0; i != 8; i++)
{
binaryArray[15 - i] = (byte)(b & 1);
b = b >> 1;
}
for (int i = 0; i != 8; i++)
{
binaryArray[23 - i] = (byte)(c & 1);
c = c >> 1;
}
return binaryArray;
} /// <summary>
/// 将图像的第55至第66字节的LSB替换为隐藏信息文件的长度
/// </summary>
private void HideInfoLength()
{
byte[] picBlock = new byte[12];
//读取原始图像的第55至第66字节的内容块
_picStream.pPosition = 54;
_picStream.Read(picBlock, 0, picBlock.Length);
byte[] lenArray = ConvertToBinaryArray(_infoStream.Length);
//置入隐藏文件的长度信息
int index = 0;
for (int i = 0; i < 4; i++)
{
//置a7,a6位
picBlock[i * 3] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3] & 253) : (picBlock[i * 3] | 2));
picBlock[i * 3] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3] & 254) : (picBlock[i * 3] | 1));
//置a5位
picBlock[i * 3 + 1] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3 + 1] & 254) : (picBlock[i * 3 + 1] | 1));
//置a4,a3,a2位
picBlock[i * 3 + 2] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3 + 2] & 251) : (picBlock[i * 3 + 2] | 4));
picBlock[i * 3 + 2] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3 + 2] & 253) : (picBlock[i * 3 + 2] | 2));
picBlock[i * 3 + 2] = (byte)((lenArray[index++] == 0) ? (picBlock[i * 3 + 2] & 254) : (picBlock[i * 3 + 2] | 1));
}
//将原始文件流重定位到第55字节处并将已嵌入长度信息的12字节块写回
_picStream.Position = 54;
_picStream.Write(picBlock, 0, picBlock.Length);
_picStream.Flush();
} /// <summary>
/// 将隐藏信息以每3个字节写入原始图像从第67字节开始的每12字节块的LSB中
/// </summary>
private void HideInfoContent()
{
int readCnt = 0;
//计算循环处理的次数
long infoLen = _infoStream.Length;
int cnt = (int)(infoLen % 3 == 0 ? infoLen / 3 : infoLen / 3 + 1);
_picStream.Position = 66;
for (int i = 0; i < cnt; i++)
{
//每次循环读取BMP图像的下一个12字节的内容
byte[] picBlock = new byte[12];
readCnt = _picStream.Read(picBlock, 0, picBlock.Length);
//读取待隐藏信息的下一个3字节内容
byte[] readBuffer = new byte[3];
_infoStream.Read(readBuffer, 0, readBuffer.Length);
byte[] infoBlock = ConvertToBinaryArray(readBuffer);
//置位操作
int index = 0;
for (int ii = 0; ii < 4; ii++)
{
//置a7,a6位
picBlock[ii * 3] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3] & 253) : (picBlock[ii * 3] | 2));
picBlock[ii * 3] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3] & 254) : (picBlock[ii * 3] | 1));
//置a5位
picBlock[ii * 3 + 1] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 1] & 254) : (picBlock[ii * 3 + 1] | 1));
//置a4,a3,a2位
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 251) : (picBlock[ii * 3 + 2] | 4));
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 253) : (picBlock[ii * 3 + 2] | 2));
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 254) : (picBlock[ii * 3 + 2] | 1));
}
_picStream.Position -= readCnt;
_picStream.Write(picBlock, 0, picBlock.Length);
}
_picStream.Flush();
} /// <summary>
/// 执行信息隐藏操作
/// </summary>
public void ExecuteEncrypt()
{
_picStream = new FileStream(_originalPicPath, FileMode.Open, FileAccess.ReadWrite);
_infoStream = new FileStream(_hidingInfoPath, FileMode.Open, FileAccess.Read);
HideInfoLength();
HideInfoContent();
_picStream.Close();
_infoStream.Close();
}
}
}请教下面代码什么意思?
//置a7,a6位
picBlock[ii * 3] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3] & 253) : (picBlock[ii * 3] | 2));
picBlock[ii * 3] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3] & 254) : (picBlock[ii * 3] | 1));
//置a5位
picBlock[ii * 3 + 1] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 1] & 254) : (picBlock[ii * 3 + 1] | 1));
//置a4,a3,a2位
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 251) : (picBlock[ii * 3 + 2] | 4));
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 253) : (picBlock[ii * 3 + 2] | 2));
picBlock[ii * 3 + 2] = (byte)((infoBlock[index++] == 0) ? (picBlock[ii * 3 + 2] & 254) : (picBlock[ii * 3 + 2] | 1));
解决方案 »
- 偶滴亲神啊,这到底是什么问题啊~~~~(下载过程中的进度条问题)
- 问一个很简单的问题
- FileSystemWatcher中能否得到访问文件的进程名
- 图像变色
- C#如何连接DB2数据库
- 关于微软许可证的问题
- 大家帮帮我,没有分了。如何吧服务器上的文件改成session("filename")的名字?最好给源码,万分感谢!
- 请问:在Win98和WinMe下,可以安装.net Framwork吗? .netFramwork1.1与.netFramwork2.0都行吗?
- DataGrid 中显示表头
- 散分!!给个理由,真的需要重画吗??C#图形编程问题
- Remoting IPC 抛出异常 端口忙: 所有的管道范例都在使用中。
- access查询中用到“like”DataTable没有返回值
什么意思啊?