黑马程序员技术交流社区
标题:
最基本的LSB数字图像隐写
[打印本页]
作者:
aisini
时间:
2014-8-18 18:11
标题:
最基本的LSB数字图像隐写
public class LSBSteganography
{
private String imgUrl;
private String password;
private byte[] infoText;
private byte[] imgByte;
private const int CB = 55; //CheckBegin 隐写检测的起始下标
private const int LB = 103; //LengthBegin 隐写文本长度的起始下标
private const int TB = 135; //TextBegin 隐写正文的起始下标
public LSBSteganography(String imgUrl, String infoText, String password)
{
this.imgUrl = imgUrl; //获取图片URL
this.password = (password + "tmppwd").Substring(0, 6); //设置密码不足补齐6位,多的只取6位
this.infoText = Encoding.Default.GetBytes(infoText); //获取隐写文本
FileStream tFS = new FileStream(imgUrl, FileMode.Open, FileAccess.ReadWrite);
this.imgByte = new byte[tFS.Length];
tFS.Read(imgByte, 0, Convert.ToInt32(tFS.Length)); //把图片信息存入imgByte
tFS.Close();
}
public String GetImgUrl()
{
return imgUrl; //返回图片URL
}
public String GetInfoText()
{
return Encoding.Default.GetString(infoText); //返回隐写信息 用户在提取信息后显示信息
}
public String LSBWrite()
{
try
{
//TB开始是真正开始隐写数据 一字节数据需要8字节图片信息来隐写
if (imgByte.Length < infoText.Length * 8 + TB) return "写入信息失败.\n图片过小无法存入全部信息";
this.SetCheckLSB(); //写入隐写标记 此处既是密码
this.SetLength(); //写入隐写长度
this.WriteInfo(); //写入文本信息
File.WriteAllBytes(imgUrl, imgByte);
return "写入信息成功.";
}
catch(Exception ex)
{
return "写入信息失败.\n" + ex.Message;
}
}
public String LSBRead()
{
try
{
//检查输入的密码是否正确
if (!this.CheckLSB()) return "读取信息失败.\n密码错误,或者图片不含隐藏信息.";
this.ReadInfo(); //读取信息到infoText
return "读取信息成功.";
}
catch(Exception ex)
{
return "读取信息失败.\n" + ex.Message;
}
}
public String LSBClear()
{
try
{
this.ClearInfo(); //擦除信息 此处方法为无脑全部置0
File.WriteAllBytes(imgUrl, imgByte);
return "擦除信息成功.";
}
catch (Exception ex)
{
return "擦除信息失败.\n" + ex.Message;
}
}
private void SetCheckLSB() //隐写密码,用于检测是否有隐写信息
{
byte[] checkStr = Encoding.Default.GetBytes(password);
for (int i = 0; i < 6; i++) //6个字符
{
for (int j = 0; j < 8; j++) //每个字符8位
{
imgByte[i * 8 + j + CB] &= ((1 << 8) - 2);
if ((checkStr[i] & (1 << j)) != 0)
imgByte[i * 8 + j + CB]++;
}
}
}
private bool CheckLSB() //读取隐写密码,于用户输入密码匹配
{
byte[] checkStr = new byte[6];
for (int i = 0; i < 6; i++) checkStr[i] = 0;
for (int i = 0; i < 6; i++) //6个字符
{
for (int j = 0; j < 8; j++) //每个字符8位
{
if ((imgByte[i * 8 + j + CB] & 1) != 0)
checkStr[i] |= Convert.ToByte(1 << j);
}
}
return Encoding.Default.GetString(checkStr) == password;
}
private int GetLength() //获取隐写文本长度
{
int length = 0;
for (int i = 0; i < 32; i++) //一个int 32位
{
if ((imgByte[i + LB] & 1) != 0)
length |= Convert.ToByte(1 << i);
}
return length;
}
private void SetLength() //写入隐写文本长度
{
int length = this.infoText.Length;
for (int i = 0; i < 32; i++) //一个int 32位
{
imgByte[i + LB] &= ((1 << 8) - 2); //末尾置0
if ((length & (1 << i)) != 0)
imgByte[i + LB]++; //如果不是0 改为1
}
}
private void WriteInfo()
{
for (int i = 0; i < infoText.Length; i++)
{
for (int j = 0; j < 8; j++) //每个字符8位
{
imgByte[i * 8 + j + TB] &= ((1 << 8) - 2); //末尾置0
if ((infoText[i] & (1 << j)) != 0)
imgByte[i * 8 + j + TB]++; //如果不是0 改为1
}
}
}
private void ReadInfo()
{
int length = this.GetLength();
infoText = new byte[length];
for (int i = 0; i < length; i++)
{
for (int j = 0; j < 8; j++) //每个字符8位
{
if ((imgByte[i * 8 + j + TB] & 1) != 0)
infoText[i] |= Convert.ToByte(1 << j);
}
}
}
private void ClearInfo()
{
int length = imgByte.Length;
for (int i = CB; i < length; i++)
{
imgByte[i] &= ((1 << 8) - 2); //末尾全部置0
}
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2