C#程序可将文本文件藏于位图中,也可导出
发布日期:2021-06-30 19:12:01
浏览次数:3
分类:技术文章
本文共 7281 字,大约阅读时间需要 24 分钟。
//使用方法: // 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; } }转载地址:https://linuxstyle.blog.csdn.net/article/details/1539931 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
感谢大佬
[***.8.128.20]2024年04月26日 13时18分57秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Oracle数据库命令
2019-04-30
有限状态机FSM
2019-04-30
Win10 Docker
2019-04-30
Python绘制动画并保存为gif/mp4 (matplotlib)
2019-04-30
PRM概率路线图
2019-04-30
ROS(六)——订阅者Subscriber的编程实现(C++ & Python)
2019-04-30
ROS(七)——话题消息的定义与使用
2019-04-30
yolov3入门实战
2019-04-30
B树 & B+树
2019-04-30
Node-Red(一)——简介与安装
2019-04-30
representation learning 表示学习/表征学习
2019-04-30
Haar特征
2019-04-30
Python 之 histogram直方图
2019-04-30
Python 之 Scatter散点图
2019-04-30
Python实现决策树 Desision Tree & 可视化
2019-04-30
决策树 Decision tree
2019-04-30
nominal和ordinal & 数据处理中四种基本数据类型
2019-04-30
Python 实现 Cross-validation
2019-04-30
Grid SearchCV(网格搜索)& Python实现
2019-04-30