该C#程序可将文本文件藏于位图中,也可导出之!

程序

//使用方法:
// BmpSafe.exe /file2bmp (input BMP) (input file to hide) [output file]
//BmpSafe.exe /bmp2file (data BMP) [output file]

using System;
using System.IO;
using System.Drawing;

public class Bitmap24Writer
{
protected Bitmap bmp;
protected int curX, curY, iRGB;
protected uint bitsLeft, bitsTotal;
protected byte r, g, b;

public Bitmap24Writer(Bitmap bmp)
{
if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
throw new ArgumentException();
// assign vars
curX = curY = iRGB = 0;
this.bmp = bmp;
bitsLeft = bitsTotal = (uint)bmp.Height * (uint)bmp.Width * 3;
}

public uint GetUnusedBitCount()
{
return bitsLeft;
}

public uint GetMaxBitStorageCount()
{
return bitsTotal;
}

public Bitmap GetBitmap()
{
return bmp;
}

public bool WriteByte(byte by)
{
if (bitsLeft < 8)
return false;

uint bits2Do = 8;

for (; curX < bmp.Width; curX++)
{
if (curY >= bmp.Height)
curY = 0;

for (; curY < bmp.Height; curY++)
{
if (bits2Do == 0)
return true;

Color col = bmp.GetPixel(curX, curY);
r = col.R;
g = col.G;
b = col.B;

for ( ; ; )
{
byte curBit = (byte)(by & 1);

switch( iRGB )
{
case 0:
r = (byte)(r & 0xFE);
r |= curBit;
break;

case 1:
g = (byte)(g & 0xFE);
g |= curBit;
break;

case 2:
b = (byte)(b & 0xFE);
b |= curBit;
break;
}
--bits2Do;
--bitsLeft;
by >>= 1;
bmp.SetPixel(curX, curY, Color.FromArgb(r, g, b));
if (iRGB == 2)
{
iRGB = 0;
break;
}
iRGB++;
if (bits2Do == 0)
return true;
}
}
}
return true;
}
}

public class Bitmap24Reader
{
protected Bitmap bmp;
protected int curX, curY, iRGB;
protected uint bitsLeft, bitsTotal;

public Bitmap24Reader(Bitmap bmp)
{
if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
throw new ArgumentException();
curX = curY = iRGB = 0;
this.bmp = bmp;
bitsLeft = bitsTotal = (uint)bmp.Height * (uint)bmp.Width * 3;
}

public uint GetUnusedBitCount()
{
return bitsLeft;
}

public uint GetMaxBitStorageCount()
{
return bitsTotal;
}

public Bitmap GetBitmap()
{
return bmp;
}

public bool ReadByte(out byte by)
{
by = 0;

if (bitsLeft < 8)
return false;

byte bit = 0;
uint bits2Do = 8;
for (; curX < bmp.Width; curX++)
{
if (curY >= bmp.Height)
curY = 0;

for (; curY < bmp.Height; curY++)
{
if (bits2Do == 0)
return true;

Color col = bmp.GetPixel(curX, curY);
for ( ; ; )
{
switch( iRGB )
{
case 0:
bit = (byte)(col.R & 1);
break;

case 1:
bit = (byte)(col.G & 1);
break;

case 2:
bit = (byte)(col.B & 1);
break;
}
--bits2Do;
--bitsLeft;
by |= (byte)(bit << 7);
if (bits2Do != 0)
by >>= 1;
if (iRGB == 2)
{
iRGB = 0;
break;
}
iRGB++;
if (bits2Do == 0)
return true;
}
}
}
return true;
}
}

public class BitmapWorks
{
public static bool Data2Bmp(FileStream dataStream, FileStream bmpStream, string outFName, out string error)
{
error = "";

Bitmap bmp;
try
{
bmp = new Bitmap(bmpStream);
}
catch
{
error = "Are you sure the specified bitmap is a valid bitmap ?";
return false;
}
if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
{
error = "Please drop only 24bit bitmaps,thanks !";
return false;
}

error += "-> Bitmap info: height=" + bmp.Height + " width=" + bmp.Width + "...\n";

if (dataStream.Length == 0)
{
error = "Input data has a not supported size of 0 !";
return false;
}
uint maxByteStorage = ((uint)bmp.Height * (uint)bmp.Width * 3) / 8;
error += "-> Up to " + (maxByteStorage-4) + " bytes could be stored in this bitmap...\n";
if (maxByteStorage < dataStream.Length + 4)
{
error = "Not enough pixel in target bitmap to hide the input data block !";
return false;
}

Bitmap24Writer bmpWriter = new Bitmap24Writer(bmp);
uint dataSize = (uint)dataStream.Length;
try
{
for (uint u = 0; u < 4; u++)
{
bmpWriter.WriteByte( (byte)dataSize );
dataSize >>= 8;
}
for (uint u = 0; u < dataStream.Length; u++)
bmpWriter.WriteByte( (byte)dataStream.ReadByte() );
}
catch
{
error = "Error while modifing the bitmap's pixels !";
return false;
}

double maxBitStorage = bmpWriter.GetMaxBitStorageCount();
double spaceUsed = (100 * (maxBitStorage - bmpWriter.GetUnusedBitCount())) / maxBitStorage;
error += "-> Space used: " + Convert.ToUInt32(spaceUsed) + "%...\n";

try
{
if ( File.Exists( outFName ) )
File.Delete( outFName );
bmpWriter.GetBitmap().Save(outFName);
}
catch
{
error = "Couldn't save output to " + outFName + " !";
return false;
}

error += "-> Output saved to: " + outFName + "...\n";

return true;
}

public static bool Bmp2Data(FileStream bmpStream, string outFName, out string error)
{
error = "";

Bitmap bmp;
try
{
bmp = new Bitmap(bmpStream);
}
catch
{
error = "Are you sure the specified bitmap is a valid bitmap ?";
return false;
}

Bitmap24Reader bmpReader;
try
{
bmpReader = new Bitmap24Reader(bmp);
}
catch (ArgumentException)
{
error = "This isn't a 24bit bitmap !";
return false;
}

FileStream outStream;
try
{
outStream = File.Create( outFName );
}
catch
{
error = "Couldn't create output file: " + outFName + " !";
return false;
}
uint dataSize = 0;
byte outByte;
try
{
for (uint u = 0; u < 4; u++)
{
if ( !bmpReader.ReadByte( out outByte ) )
throw new Exception();
dataSize |= (uint)( outByte << 8*3 );
if (u != 3)
dataSize >>= 8;
}
error += "-> Size of hidden data: " + dataSize + " bytes...\n";
for (uint u = 0; u < dataSize; u++)
{
if ( !bmpReader.ReadByte( out outByte ) )
throw new Exception();
outStream.WriteByte( outByte );
}
}
catch
{
error = "Exception caught while reading the hidden data !";
return false;
}
finally
{
outStream.Close();
}

error += "-> Output saved to: " + outFName + "...\n";

return true;
}

}

class BmpSafe
{
public static string cmdLine =
"Command line:\n" +
" BmpSafe.exe /file2bmp (input BMP) (input file to hide) [output file]\n" +
" BmpSafe.exe /bmp2file (data BMP) [output file]";

private static string serviceOne = "/file2bmp";
private static string serviceTwo = "/bmp2file";

[STAThread]
static void Main(string[] args)
{
Console.WriteLine(
"BmpSafe - hide files in 24bit bitmaps\n" +
" a little steganografie implementation\n" +
" by yoda\n" +
"-------------------------------------------------------------------------------\n");

string inFile = "", inBmp, outFile;
bool bFile2Bmp;
if (args.Length < 2)
{
Console.WriteLine("!! Invalid number of arguments :(");
Console.WriteLine(cmdLine);
return; // ERR
}
if ( String.Compare(args[0], serviceOne, true) == 0 )
bFile2Bmp = true;
else if ( String.Compare(args[0], serviceTwo, true) == 0)
bFile2Bmp = false;
else
{
Console.WriteLine("!! First parameters must be either \"/file2bmp\" or \"/bmp2file\" !");
return;
}

inBmp = args[1];
if (bFile2Bmp)
{
if (args.Length < 3)
{
Console.WriteLine("!! Invalid number of arguments :(");
Console.WriteLine(cmdLine);
return;
}
inFile = args[2];
if (args.Length > 3)
outFile = args[3];
else
outFile = "Secret.BMP";
}
else
{
if (args.Length > 2)
outFile = args[2];
else
outFile = "Secret.bin";
}

Console.WriteLine("-> Processing input...");
try
{
string err;
bool ret;

if (bFile2Bmp)
ret = BitmapWorks.Data2Bmp(
File.OpenRead(inFile),
File.OpenRead(inBmp),
outFile,
out err );
else
ret = BitmapWorks.Bmp2Data(
File.OpenRead(inBmp),
outFile,
out err);
if (!ret)
{
Console.WriteLine("!! " + err);
return;
}
else
Console.Write( err );
}
catch(FileNotFoundException)
{
Console.WriteLine("!! At least one file could not be found :(");
return;
}
catch
{
Console.WriteLine("!! An exception occurred :(");
return;
}

Console.WriteLine("-> Job done...");

return;
}
}

时间: 2024-11-08 23:14:26

该C#程序可将文本文件藏于位图中,也可导出之!的相关文章

Excel 2007中导入或导出文本文件

使用 Microsoft Office Excel从文本文件导入数据有两种方式:可以在Excel中打开文本文件,也可以导入作为外部数据区域 (外部数据区域:从Excel的外部(如,数据库或文本文件)导入工作表的数据区域.在Excel中,可为外部数据区域中的数据设置格式或用其进行计算,就如同对其他任何数据一样.)的文本文件.要将数据从Excel导出到文本文件,请使用"另存为"命令. 以下是常用的两种文本文件格式: ·带分隔符的文本文件 (.txt),其中通常用制表符(ASCII 字符代码

ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务解决

环境:Oracle 11g R2 + PL SQL Developer + SQL Plus 问题:Oracle主服务和监听器服务已经启 动,使用SQL Plus能够正常连接,使用PL SQL Developer连接报次错误:ORA-12514: TNS: 监听程序当前无法 识别连接描述符中请求的服务.如图: 解决: 打开H:\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMIN(不同机器目录可能不同 )目录下的listener.ora文件,发现此文件内容如下

界面-如何使打开的其他程序或者文档在MFC窗口中显示,而不是新打开一个窗口

问题描述 如何使打开的其他程序或者文档在MFC窗口中显示,而不是新打开一个窗口 我想在程序界面中指定一个区域,用于显示被打开的其他程序或者文档的界面.可是我用ShellExecute函数打开指定的那个文档和程序的时候,总是会再启动另一个窗口,效果就像是直接点击打开那个文件一样. 解决方案 将mfc窗口设置为其它程序的父窗口 解决方案二: 参考:程序只允许打开唯一实例且所有关联文档都在同一实例内打开的一揽子解决办法http://blog.csdn.net/IfI/article/details/1

button-以程序的方式从添加的按钮中获得OnClick()事件

问题描述 以程序的方式从添加的按钮中获得OnClick()事件 我用以下代码添加了一些按钮: for (int i=0; i<XML.size(); i++) { //添加按钮 ToggleButton b = new ToggleButton(this); // 参数设置 lefttextv.setLayoutParams(lleft); b.setLayoutParams(bright); //自定义按钮 b.setOnClickListener(this); b.setId(id_butt

想做一个vc程序,后台监控指定文件夹中是否存在数据库文件,如果有则将文件内容上传到服务器数据库中。

问题描述 想做一个vc程序,后台监控指定文件夹中是否存在数据库文件,如果有则将文件内容上传到服务器数据库中. 有说可以写服务来后台监控的,但是我不太明白原理,服务是怎么实现后台监控, vc倒是可以直接生成一个服务,但是不清楚原理,完全不知道应该从哪下手. 希望有高手给解答一下. 解决方案 参考:http://blog.sina.com.cn/s/blog_a6fb6cc901017us1.html

xe10的c++builder中开发ios程序,如何在苹果的模拟器中运行

问题描述 xe10的c++builder中开发ios程序,如何在苹果的模拟器中运行 30C xe10的delphi中可以直接开发程序直接运行在苹果系统的虚拟机里,但是c++builder中却不能在模拟器中运行.不知道如何做,谢谢! 解决方案 http://www.embarcadero.com/products/cbuilder

gradle打包android程序时,如何修改java文件中的属性值

问题描述 gradle打包android程序时,如何修改java文件中的属性值 工程有个文件例如1.java文件:其中有个public final static String URL = "/www.baidu.com"; 现在的问题是如何在用gradle打包的时候可以更换1.java文件中的URL? ant打包就可以写不同的build.xml,在build.xml中更换URL的字符串,在利用ant构建的时候通过编译不同的build.xml来达到更换URL的目的. 现在不知道gradl

帮我看看吧,这些修改密码的程序,在火车订票系统中怎么定义的

问题描述 帮我看看吧,这些修改密码的程序,在火车订票系统中怎么定义的 this->UpdateData(true); usenameset set; if(m_name=="") ::MessageBox(NULL,"用户名不能为空!","错误",MB_ICONINFORMATION); else{set.Open(CRecordset::dynaset,_T("select * from usename where use='&

紧急紧急-ora 12514 tns监听程序当前无法识别连接描述符中的请求

问题描述 ora 12514 tns监听程序当前无法识别连接描述符中的请求 解决方案 主机字符串不对,进net manager配置一下数据库连接. 解决方案二: 查看一下你的连接字符串,有参数没有配置正确 解决方案三: Oracle Clientm没有安装和配置