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

原创 2004年10月20日 12:12:00
http://blog.csdn.net/yiruoyun/archive/2004/10/18/141514.aspx

//使用方法:
// 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;
 }
}

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

//使用方法:// BmpSafe.exe /file2bmp (input BMP) (input file to hide) [output file]//BmpSafe.exe /bmp2fil...
  • yiruoyun
  • yiruoyun
  • 2004年10月18日 17:47
  • 1791

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

//使用方法:// BmpSafe.exe /file2bmp (input BMP) (input file to hide) [output file]//BmpSafe.exe /bmp2fil...
  • cacacy
  • cacacy
  • 2004年10月18日 12:18
  • 728

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

//使用方法: // BmpSafe.exe /file2bmp (input BMP) (input file to hide) [output file] //BmpSafe.exe /bmp2f...
  • 21aspnet
  • 21aspnet
  • 2007年03月24日 16:13
  • 3036

愿在夜而为烛,照玉容于两楹;悲扶桑之舒光,奄灭景而藏明!

愿在衣而为领,承华首之余芳;悲罗襟之宵离,怨秋夜之未央! 愿在裳而为带,束窈窕之纤身;嗟温凉之异气,或脱故而服新! 愿在发而为泽,刷玄鬓于颓肩;悲佳人之屡沐,从白水而枯煎! 愿在眉而为黛,...
  • qq_28623593
  • qq_28623593
  • 2015年05月31日 12:46
  • 1128

43节从文本文件中读入数据!

这一讲是上一讲的拓展 例:编程序,实现文本文件的复制 代码分析: #include #include int main() { FILE *fint,*fout; char ...
  • wzting
  • wzting
  • 2015年12月25日 22:15
  • 263

C/C++信息隐写术(三)之txt文件藏入BMP文件

C/C++信息隐写术(三)之txt文件藏入BMP文件
  • qq78442761
  • qq78442761
  • 2017年02月06日 16:19
  • 1911

打开图片,提示:该文件没有程序与之关联来执行该操作。请在控制面板的文件夹选项中创建关联

在电脑中打开图片,不能正常打开,弹出提示信息:该文件没有程序与之关联来执行该操作。请在控制面板的文件夹选项中创建关联         从网上找到的解决方法:     选中图片,点右键,在弹出的...
  • wander2
  • wander2
  • 2015年01月30日 17:15
  • 3834

文件藏于图片的三个思路

文件藏于图片中的三个思路及其源码: 1.追加在图片文件后面 2、3.直接结合到PNG和ico文件的相关节里面,使其成为图片的一部分。...
  • u013761036
  • u013761036
  • 2016年12月18日 15:51
  • 1384

其知可及,其愚不可及也

宁武子 邦有道则知 邦无道则愚 其知可及也 其愚不可及            ——《论语.公冶长》 成语“愚不可及”由此而来,只不过现在使用的意思变了,变成了贬义。...
  • fulminate
  • fulminate
  • 2014年02月20日 11:24
  • 1883

【node.js】本地模式安装express:'express' 不是内部或外部命令,也不是可运行的程序或批处理文件。

今天闲来无事想起了node.js,因此到网上下载了一个node.js的安装程序进行安装。...
  • MCpang
  • MCpang
  • 2014年05月22日 18:19
  • 29154
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[引用]该C#程序可将文本文件藏于位图中,也可导出之!
举报原因:
原因补充:

(最多只允许输入30个字)