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

  1<pre>   
  2using System;   
  3using System.IO;   
  4using System.Drawing; 
  5
  6public class Bitmap24Writer   
  7{   
  8protected Bitmap bmp;   
  9protected int curX, curY, iRGB;   
 10protected uint bitsLeft, bitsTotal;   
 11protected byte r, g, b; 
 12
 13public Bitmap24Writer(Bitmap bmp)   
 14{   
 15if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)   
 16throw new ArgumentException();   
 17// assign vars   
 18curX = curY = iRGB = 0;   
 19this.bmp = bmp;   
 20bitsLeft = bitsTotal = (uint)bmp.Height * (uint)bmp.Width * 3;   
 21} 
 22
 23public uint GetUnusedBitCount()   
 24{   
 25return bitsLeft;   
 26} 
 27
 28public uint GetMaxBitStorageCount()   
 29{   
 30return bitsTotal;   
 31} 
 32
 33public Bitmap GetBitmap()   
 34{   
 35return bmp;   
 36} 
 37
 38public bool WriteByte(byte by)   
 39{   
 40if (bitsLeft &lt; 8)   
 41return false; 
 42
 43uint bits2Do = 8; 
 44
 45for (; curX &lt; bmp.Width; curX++)   
 46{   
 47if (curY &gt;= bmp.Height)   
 48curY = 0; 
 49
 50for (; curY &lt; bmp.Height; curY++)   
 51{   
 52if (bits2Do == 0)   
 53return true; 
 54
 55Color col = bmp.GetPixel(curX, curY);   
 56r = col.R;   
 57g = col.G;   
 58b = col.B; 
 59
 60for ( ; ; )   
 61{   
 62byte curBit = (byte)(by &amp; 1); 
 63
 64switch( iRGB )   
 65{   
 66case 0:   
 67r = (byte)(r &amp; 0xFE);   
 68r |= curBit;   
 69break; 
 70
 71case 1:   
 72g = (byte)(g &amp; 0xFE);   
 73g |= curBit;   
 74break; 
 75
 76case 2:   
 77b = (byte)(b &amp; 0xFE);   
 78b |= curBit;   
 79break;   
 80}   
 81\--bits2Do;   
 82\--bitsLeft;   
 83by &gt;&gt;= 1;   
 84bmp.SetPixel(curX, curY, Color.FromArgb(r, g, b));   
 85if (iRGB == 2)   
 86{   
 87iRGB = 0;   
 88break;   
 89}   
 90iRGB++;   
 91if (bits2Do == 0)   
 92return true;   
 93}   
 94}   
 95}   
 96return true;   
 97}   
 98} 
 99
100public class Bitmap24Reader   
101{   
102protected Bitmap bmp;   
103protected int curX, curY, iRGB;   
104protected uint bitsLeft, bitsTotal; 
105
106public Bitmap24Reader(Bitmap bmp)   
107{   
108if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)   
109throw new ArgumentException();   
110curX = curY = iRGB = 0;   
111this.bmp = bmp;   
112bitsLeft = bitsTotal = (uint)bmp.Height * (uint)bmp.Width * 3;   
113} 
114
115public uint GetUnusedBitCount()   
116{   
117return bitsLeft;   
118} 
119
120public uint GetMaxBitStorageCount()   
121{   
122return bitsTotal;   
123} 
124
125public Bitmap GetBitmap()   
126{   
127return bmp;   
128} 
129
130public bool ReadByte(out byte by)   
131{   
132by = 0; 
133
134if (bitsLeft &lt; 8)   
135return false; 
136
137byte bit = 0;   
138uint bits2Do = 8;   
139for (; curX &lt; bmp.Width; curX++)   
140{   
141if (curY &gt;= bmp.Height)   
142curY = 0; 
143
144for (; curY &lt; bmp.Height; curY++)   
145{   
146if (bits2Do == 0)   
147return true; 
148
149Color col = bmp.GetPixel(curX, curY);   
150for ( ; ; )   
151{   
152switch( iRGB )   
153{   
154case 0:   
155bit = (byte)(col.R &amp; 1);   
156break; 
157
158case 1:   
159bit = (byte)(col.G &amp; 1);   
160break; 
161
162case 2:   
163bit = (byte)(col.B &amp; 1);   
164break;   
165}   
166\--bits2Do;   
167\--bitsLeft;   
168by |= (byte)(bit &lt;&lt; 7);   
169if (bits2Do != 0)   
170by &gt;&gt;= 1;   
171if (iRGB == 2)   
172{   
173iRGB = 0;   
174break;   
175}   
176iRGB++;   
177if (bits2Do == 0)   
178return true;   
179}   
180}   
181}   
182return true;   
183}   
184} 
185
186public class BitmapWorks   
187{   
188public static bool Data2Bmp(FileStream dataStream, FileStream bmpStream, string outFName, out string error)   
189{   
190error = ""; 
191
192Bitmap bmp;   
193try   
194{   
195bmp = new Bitmap(bmpStream);   
196}   
197catch   
198{   
199error = "Are you sure the specified bitmap is a valid bitmap ?";   
200return false;   
201}   
202if (bmp.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)   
203{   
204error = "Please drop only 24bit bitmaps,thanks !";   
205return false;   
206} 
207
208error += "-&gt; Bitmap info: height=" + bmp.Height + " width=" + bmp.Width + "...\n"; 
209
210if (dataStream.Length == 0)   
211{   
212error = "Input data has a not supported size of 0 !";   
213return false;   
214}   
215uint maxByteStorage = ((uint)bmp.Height * (uint)bmp.Width * 3) / 8;   
216error += "-&gt; Up to " + (maxByteStorage-4) + " bytes could be stored in this bitmap...\n";   
217if (maxByteStorage &lt; dataStream.Length + 4)   
218{   
219error = "Not enough pixel in target bitmap to hide the input data block !";   
220return false;   
221} 
222
223Bitmap24Writer bmpWriter = new Bitmap24Writer(bmp);   
224uint dataSize = (uint)dataStream.Length;   
225try   
226{   
227for (uint u = 0; u &lt; 4; u++)   
228{   
229bmpWriter.WriteByte( (byte)dataSize );   
230dataSize &gt;&gt;= 8;   
231}   
232for (uint u = 0; u &lt; dataStream.Length; u++)   
233bmpWriter.WriteByte( (byte)dataStream.ReadByte() );   
234}   
235catch   
236{   
237error = "Error while modifing the bitmap's pixels !";   
238return false;   
239} 
240
241double maxBitStorage = bmpWriter.GetMaxBitStorageCount();   
242double spaceUsed = (100 * (maxBitStorage - bmpWriter.GetUnusedBitCount())) / maxBitStorage;   
243error += "-&gt; Space used: " + Convert.ToUInt32(spaceUsed) + "%...\n"; 
244
245try   
246{   
247if ( File.Exists( outFName ) )   
248File.Delete( outFName );   
249bmpWriter.GetBitmap().Save(outFName);   
250}   
251catch   
252{   
253error = "Couldn't save output to " + outFName + " !";   
254return false;   
255} 
256
257error += "-&gt; Output saved to: " + outFName + "...\n"; 
258
259return true;   
260} 
261
262public static bool Bmp2Data(FileStream bmpStream, string outFName, out string error)   
263{   
264error = ""; 
265
266Bitmap bmp;   
267try   
268{   
269bmp = new Bitmap(bmpStream);   
270}   
271catch   
272{   
273error = "Are you sure the specified bitmap is a valid bitmap ?";   
274return false;   
275} 
276
277Bitmap24Reader bmpReader;   
278try   
279{   
280bmpReader = new Bitmap24Reader(bmp);   
281}   
282catch (ArgumentException)   
283{   
284error = "This isn't a 24bit bitmap !";   
285return false;   
286} 
287
288FileStream outStream;   
289try   
290{   
291outStream = File.Create( outFName );   
292}   
293catch   
294{   
295error = "Couldn't create output file: " + outFName + " !";   
296return false;   
297}   
298uint dataSize = 0;   
299byte outByte;   
300try   
301{   
302for (uint u = 0; u &lt; 4; u++)   
303{   
304if ( !bmpReader.ReadByte( out outByte ) )   
305throw new Exception();   
306dataSize |= (uint)( outByte &lt;&lt; 8*3 );   
307if (u != 3)   
308dataSize &gt;&gt;= 8;   
309}   
310error += "-&gt; Size of hidden data: " + dataSize + " bytes...\n";   
311for (uint u = 0; u &lt; dataSize; u++)   
312{   
313if ( !bmpReader.ReadByte( out outByte ) )   
314throw new Exception();   
315outStream.WriteByte( outByte );   
316}   
317}   
318catch   
319{   
320error = "Exception caught while reading the hidden data !";   
321return false;   
322}   
323finally   
324{   
325outStream.Close();   
326} 
327
328error += "-&gt; Output saved to: " + outFName + "...\n"; 
329
330return true;   
331} 
332
333} 
334
335class BmpSafe   
336{   
337public static string cmdLine =   
338"Command line:\n" +   
339" BmpSafe.exe /file2bmp (input BMP) (input file to hide) [output file]\n" +   
340" BmpSafe.exe /bmp2file (data BMP) [output file]"; 
341
342private static string serviceOne = "/file2bmp";   
343private static string serviceTwo = "/bmp2file"; 
344
345[STAThread]   
346static void Main(string[] args)   
347{   
348Console.WriteLine(   
349"BmpSafe - hide files in 24bit bitmaps\n" +   
350" a little steganografie implementation\n" +   
351" by yoda\n" +   
352"-------------------------------------------------------------------------------\n"); 
353
354string inFile = "", inBmp, outFile;   
355bool bFile2Bmp;   
356if (args.Length &lt; 2)   
357{   
358Console.WriteLine("!! Invalid number of arguments :(");   
359Console.WriteLine(cmdLine);   
360return; // ERR   
361}   
362if ( String.Compare(args[0], serviceOne, true) == 0 )   
363bFile2Bmp = true;   
364else if ( String.Compare(args[0], serviceTwo, true) == 0)   
365bFile2Bmp = false;   
366else   
367{   
368Console.WriteLine("!! First parameters must be either \"/file2bmp\" or \"/bmp2file\" !");   
369return;   
370} 
371
372inBmp = args[1];   
373if (bFile2Bmp)   
374{   
375if (args.Length &lt; 3)   
376{   
377Console.WriteLine("!! Invalid number of arguments :(");   
378Console.WriteLine(cmdLine);   
379return;   
380}   
381inFile = args[2];   
382if (args.Length &gt; 3)   
383outFile = args[3];   
384else   
385outFile = "Secret.BMP";   
386}   
387else   
388{   
389if (args.Length &gt; 2)   
390outFile = args[2];   
391else   
392outFile = "Secret.bin";   
393}   
394  
395Console.WriteLine("-&gt; Processing input...");   
396try   
397{   
398string err;   
399bool ret; 
400
401if (bFile2Bmp)   
402ret = BitmapWorks.Data2Bmp(   
403File.OpenRead(inFile),   
404File.OpenRead(inBmp),   
405outFile,   
406out err );   
407else   
408ret = BitmapWorks.Bmp2Data(   
409File.OpenRead(inBmp),   
410outFile,   
411out err);   
412if (!ret)   
413{   
414Console.WriteLine("!! " + err);   
415return;   
416}   
417else   
418Console.Write( err );   
419}   
420catch(FileNotFoundException)   
421{   
422Console.WriteLine("!! At least one file could not be found :(");   
423return;   
424}   
425catch   
426{   
427Console.WriteLine("!! An exception occurred :(");   
428return;   
429} 
430
431Console.WriteLine("-&gt; Job done..."); 
432
433return;   
434}   
435}   
436</pre>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus