将保存重要信息,如银行卡密码的文本文件隐藏到ARGB8888的A通道。

bitmap.h

  1. #ifndef BMP_H
  2. #define BMP_H
  3.  
  4. #include <fstream>
  5. #include <string>
  6. #include <iostream>
  7.  
  8. #define DEBUG 0
  9.  
  10. #define LOG std::cout
  11. #define HEX std::hex
  12. #define DEC std::dec
  13.  
  14. #define FLAG_0 (0xFF)
  15. #define FLAG_1 (0xEE)
  16. #define FLAG_2 (0xDD)
  17. #define FLAG_3 (0xCC)
  18.  
  19. #define DATA_CODE (0xCC)
  20.  
  21. #define BYTE_PER_PIXEL (4)
  22.  
  23. #pragma pack(push, 1)
  24. typedef struct
  25. {
  26. uint16_t bfType; // Type of bitmap, in windows, always 'BM'
  27. uint32_t bfSize; // Size of the bitmap file
  28. uint16_t bfReserved1; // reserved feild
  29. uint16_t bfReserved2; // reserved feild
  30. uint32_t bfOffBits; // the start address of the bitmap data
  31. }BMP_FILE_HEADER;
  32.  
  33. typedef struct
  34. {
  35. uint32_t biSize; // size of this struct
  36. uint32_t biWidth; // image width, unit is pixel
  37. uint32_t biHeight; // image height, unit is pixel
  38. uint16_t biPlanes; // alsways 1
  39. uint16_t biBitCount; // color depth of the image, 1, 4, 8, 16, 24 and 32
  40. uint32_t biCompression; // compression type, 0=no compress, 1=RLE8 compress
  41. // 2=RLE4 compress, 3=pixel color mask
  42. uint32_t biSizeImage; // pixel data size of the image
  43. uint32_t biXPelsPerMeter; // H resolution, pixel per meter
  44. uint32_t biYPelsPerMeter; // V resolution, pixel per meter
  45. uint32_t biClrUsed; // color number that used, 0=all color
  46. uint32_t biClrImportant; // important color amount, 0=all color important
  47. }BMP_INFO_HEADER;
  48. #pragma pacn(pop)
  49.  
  50. class Bitmap
  51. {
  52. private:
  53. BMP_FILE_HEADER m_fileHeader;
  54. BMP_INFO_HEADER m_infoHeader;
  55.  
  56. std::string m_bmpPath;
  57. bool m_parseFlag;
  58. public:
  59. Bitmap(std::string path);
  60. ~Bitmap();
  61. bool bmpParse();
  62. uint32_t getBmpSize();
  63. uint32_t getBmpDataAddr();
  64. std::string getBmpPath();
  65. uint32_t getBmpPixelNum();
  66. };
  67.  
  68. class DataHider
  69. {
  70. private:
  71. uint8_t m_flags[4];
  72. uint8_t m_length[4];
  73. Bitmap m_bitmapHeader;
  74. std::string m_dataFilePath;
  75.  
  76. bool isAHider();
  77. uint32_t getFileSize(std::ifstream &in);
  78. bool readTransByte(std::fstream &file, uint8_t &val, int pos);
  79. bool writeTransByte(std::fstream &file, uint8_t val, int pos);
  80. void length2Byte(uint32_t length);
  81. uint32_t byte2Length();
  82. public:
  83. DataHider(std::string dataPath, std::string bmpPath);
  84. ~DataHider();
  85. bool doEncode();
  86. bool doDecode();
  87. };
  88.  
  89. #endif // BMP_H

  bitmap.cpp

  1. #include "bitmap.h"
  2.  
  3. Bitmap::Bitmap(std::string path)
  4. : m_fileHeader(), m_infoHeader(), m_bmpPath(path), m_parseFlag(false)
  5. {
  6. }
  7.  
  8. Bitmap::~Bitmap()
  9. {
  10. }
  11.  
  12. bool Bitmap::bmpParse()
  13. {
  14. std::ifstream in;
  15. in.open(m_bmpPath, std::ios::binary);
  16.  
  17. in.read((char *)&m_fileHeader, sizeof(m_fileHeader));
  18. /*char * p = (char *)&m_fileHeader;
  19. for(uint32_t i=0; i<sizeof(m_fileHeader); ++i)
  20. {
  21. in.read(p, 1);
  22. LOG << HEX << (int)*p << " ";
  23. ++p;
  24. }*/
  25. if( !in.good() )
  26. {
  27. LOG << "read bitmap file head error!\n";
  28. in.close();
  29. return false;
  30. }
  31.  
  32. in.read((char *)&m_infoHeader, sizeof(m_infoHeader));
  33. /* LOG << "read bitmap information header!\n";
  34. p = (char *)&m_infoHeader;
  35. for(uint32_t i=0; i<sizeof(m_infoHeader); ++i)
  36. {
  37. in.read(p, 1);
  38. LOG << HEX << (int)*p << " ";
  39. ++p;
  40. }*/
  41. if( !in.good() )
  42. {
  43. LOG << "read bitmap information header error!\n";
  44. in.close();
  45. return false;
  46. }
  47.  
  48. in.close();
  49. m_parseFlag = true;
  50.  
  51. #if 1 == DEBUG
  52. LOG << "Bitmap file header:"
  53. << "\nbfType: " << HEX << (int)m_fileHeader.bfType
  54. << "\nbfSize: " << (int)m_fileHeader.bfSize
  55. << "\nbfReserved1: " << (int)m_fileHeader.bfReserved1
  56. << "\nbfReserved2: " << (int)m_fileHeader.bfReserved2
  57. << "\nbfOffBits: " << (int)m_fileHeader.bfOffBits
  58. << "\nBitmap information header:"
  59. << "\nbiSize: " << (int)m_infoHeader.biSize << DEC << "\n";
  60. #endif
  61.  
  62. return true;
  63. }
  64.  
  65. uint32_t Bitmap::getBmpSize()
  66. {
  67. if(!m_parseFlag)
  68. {
  69. LOG << "please do bitmap parse first!\n";
  70. }
  71. return m_fileHeader.bfSize;
  72. }
  73.  
  74. std::string Bitmap::getBmpPath()
  75. {
  76. return m_bmpPath;
  77. }
  78.  
  79. uint32_t Bitmap::getBmpDataAddr()
  80. {
  81. if(!m_parseFlag)
  82. {
  83. LOG << "please do bitmap parse first!\n";
  84. }
  85. return m_fileHeader.bfOffBits;
  86. }
  87.  
  88. uint32_t Bitmap::getBmpPixelNum()
  89. {
  90. return m_infoHeader.biWidth * m_infoHeader.biHeight;
  91. }
  92.  
  93. DataHider::DataHider(std::string dataPath, std::string bmpPath)
  94. : m_bitmapHeader(bmpPath), m_dataFilePath(dataPath)
  95. {
  96. }
  97.  
  98. DataHider::~DataHider()
  99. {
  100. }
  101.  
  102. bool DataHider::isAHider()
  103. {
  104. return (m_flags[0] == FLAG_0) &
  105. (m_flags[1] == FLAG_1) &
  106. (m_flags[2] == FLAG_2) &
  107. (m_flags[3] == FLAG_3);
  108. }
  109.  
  110. uint32_t DataHider::getFileSize(std::ifstream &in)
  111. {
  112. if(!in.good())
  113. {
  114. LOG << "the data file has some error.\n";
  115. return false;
  116. }
  117.  
  118. uint32_t pos = in.tellg();
  119. in.seekg(0, std::ios_base::end);
  120. uint32_t size = in.tellg();
  121. in.seekg(pos, std::ios_base::beg);
  122.  
  123. return size;
  124. }
  125.  
  126. bool DataHider::readTransByte(std::fstream &file, uint8_t &val, int pos)
  127. {
  128. file.seekg(m_bitmapHeader.getBmpDataAddr()+BYTE_PER_PIXEL*pos, std::ios_base::beg);
  129. #if DEBUG == 1
  130. LOG << "pos " << HEX << m_bitmapHeader.getBmpDataAddr()+BYTE_PER_PIXEL*pos << "\n";
  131. #endif
  132. file.read((char *)&val, 1);
  133. return file.good();
  134. }
  135.  
  136. bool DataHider::writeTransByte(std::fstream &file, uint8_t val, int pos)
  137. {
  138. file.seekp(m_bitmapHeader.getBmpDataAddr()+BYTE_PER_PIXEL*pos, std::ios_base::beg);
  139. file.write((char *)&val, 1);
  140. return file.good();
  141. }
  142.  
  143. void DataHider::length2Byte(uint32_t length)
  144. {
  145. for(uint32_t i=0; i<4; ++i)
  146. m_length[i] = (uint8_t)(length >> (i*8)) & 0xFF;
  147. #if DEBUG == 1
  148. LOG << "length: " << length << "\n"
  149. << (int)m_length[0] << " "
  150. << (int)m_length[1] << " "
  151. << (int)m_length[2] << " "
  152. << (int)m_length[3] << "\n";
  153. #endif
  154. }
  155.  
  156. uint32_t DataHider::byte2Length()
  157. {
  158. uint32_t length = 0;
  159. uint32_t temp;
  160. for(uint32_t i=0; i<4; ++i)
  161. {
  162. temp = m_length[i];
  163. #if DEBUG == 1
  164. LOG << "temp: " << temp << "\n";
  165. #endif
  166. temp <<= (i*8);
  167. #if DEBUG == 1
  168. LOG << "temp: " << temp << "\n";
  169. #endif
  170. length += temp;
  171. }
  172.  
  173. #if DEBUG == 1
  174. LOG << "length: " << length << "\n";
  175. #endif
  176.  
  177. return length;
  178. }
  179.  
  180. bool DataHider::doEncode()
  181. {
  182. m_bitmapHeader.bmpParse();
  183.  
  184. std::ifstream dataFile;
  185. dataFile.open(m_dataFilePath, std::ios::binary);
  186. if(!dataFile.good())
  187. {
  188. LOG << "open " << m_dataFilePath << " failed!\n";
  189. return false;
  190. }
  191. uint32_t dataSize = getFileSize(dataFile);
  192. if(dataSize > m_bitmapHeader.getBmpPixelNum() + 8) // flag size add length size
  193. {
  194. LOG << "data is too big to save into the bitmap!\n";
  195. dataFile.close();
  196. return false;
  197. }
  198.  
  199. std::fstream bmpFile;
  200. bmpFile.open(m_bitmapHeader.getBmpPath(), std::ios_base::binary|
  201. std::ios_base::out|std::ios_base::in);
  202. // |std::ios_base::ate|std::ios_base::app
  203. if(!bmpFile.good())
  204. {
  205. LOG << "open " << m_bitmapHeader.getBmpPath() << " failed!\n";
  206. dataFile.close();
  207. return false;
  208. }
  209. dataFile.seekg(0, std::ios_base::beg);
  210.  
  211. // flags
  212. m_flags[0] = FLAG_0;
  213. m_flags[1] = FLAG_1;
  214. m_flags[2] = FLAG_2;
  215. m_flags[3] = FLAG_3;
  216.  
  217. for(uint32_t i=0; i<4; ++i)
  218. writeTransByte(bmpFile, m_flags[i], i);
  219.  
  220. // length
  221. length2Byte(dataSize);
  222.  
  223. for(uint32_t i=0; i<4; ++i)
  224. writeTransByte(bmpFile, m_length[i], i+4);
  225.  
  226. // pos start at the 8th pixel
  227. int pos = 0;
  228. uint8_t data;
  229. while(pos < dataSize)
  230. {
  231. dataFile.read((char *)&data, 1);
  232. #if DEBUG == 1
  233. LOG << HEX << (int)data << " ";
  234. #endif
  235. data ^= DATA_CODE;
  236. writeTransByte(bmpFile, data, pos+8);
  237. ++pos;
  238. }
  239.  
  240. bmpFile.close();
  241. dataFile.close();
  242. return true;
  243. }
  244.  
  245. bool DataHider::doDecode()
  246. {
  247. m_bitmapHeader.bmpParse();
  248.  
  249. std::fstream bmpFile;
  250. bmpFile.open(m_bitmapHeader.getBmpPath(), std::ios_base::binary|std::ios_base::in);
  251. if(!bmpFile.good())
  252. {
  253. LOG << "open " << m_bitmapHeader.getBmpPath() << " failed!\n";
  254. return false;
  255. }
  256. bmpFile.seekg(0, std::ios_base::beg);
  257.  
  258. // flags
  259. for(uint32_t i=0; i<4; ++i)
  260. {
  261. readTransByte(bmpFile, m_flags[i], i);
  262. #if DEBUG
  263. LOG << HEX << (int)m_flags[i] << " ";
  264. #endif
  265. }
  266.  
  267. if( !isAHider() )
  268. {
  269. LOG << "this bitmap is not a hider file!\n";
  270. bmpFile.close();
  271. return false;
  272. }
  273.  
  274. // length
  275. for(uint32_t i=0; i<4; ++i)
  276. readTransByte(bmpFile, m_length[i], i+4);
  277.  
  278. #if DEBUG == 1
  279. LOG << (int)m_length[0] << " "
  280. << (int)m_length[1] << " "
  281. << (int)m_length[2] << " "
  282. << (int)m_length[3] << "\n";
  283. #endif
  284.  
  285. uint32_t dataSize = byte2Length();
  286.  
  287. std::ofstream dataFile;
  288. dataFile.open(m_dataFilePath, std::ios::binary);
  289. if(!dataFile.good())
  290. {
  291. LOG << "open " << m_dataFilePath << " failed!\n";
  292. bmpFile.close();
  293. return false;
  294. }
  295. // pos start at the 8th pixel
  296. int pos = 0;
  297. uint8_t data;
  298. while(pos < dataSize)
  299. {
  300. readTransByte(bmpFile, data, pos+8);
  301. data ^= DATA_CODE;
  302. dataFile.write((char *)&data, 1);
  303. ++pos;
  304.  
  305. }
  306.  
  307. bmpFile.close();
  308. dataFile.close();
  309. return true;
  310. }

  main.cpp

  1. #include <iostream>
  2. #include "bitmap.h"
  3. using namespace std;
  4.  
  5. int main(int argc, char **argv)
  6. {
  7. cout << "Hello world!" << endl;
  8.  
  9. if(argc < 4)
  10. {
  11. cout << "please type the right command!\n"
  12. << "DataHider encode ./data.txt ./ARGB8888.bmp\n"
  13. << "or DataHider decode ./data_out.txt ./ARGB8888.bmp\n";
  14. return -1;
  15. }
  16.  
  17. string mode = argv[1];
  18. string dataFile = argv[2];
  19. string bmpFile = argv[3];
  20.  
  21. if(mode == "encode")
  22. {
  23. cout << "encoder\n";
  24. DataHider encoder(dataFile, bmpFile);
  25. encoder.doEncode();
  26. }
  27. else if(mode == "decode")
  28. {
  29. cout << "decoder\n";
  30. DataHider decoder(dataFile, bmpFile);
  31. decoder.doDecode();
  32. }
  33.  
  34. return 0;
  35. }

  

Hide Data into bitmap with ARGB8888 format的更多相关文章

  1. [Data Structure] Bit-map空间压缩和快速排序去重

    Bit-map是一种很巧妙的数据存储结构.所谓的Bit-map就是用一个bit位来标记某个元素对应的Value,而Key即是该元素.由于采用了Bit为单位来存储数据,可以大大节省存储空间.Bit-ma ...

  2. 转:Hide data inside pointers(在指针中隐藏数据)

    该文介绍了如何使用指针中一些未使用的位来隐藏一些数据. When we write C code, pointers are everywhere. We can make a little extr ...

  3. 3ds Max File Format (Part 3: The department of redundancy department; Config)

    Now we'll have a look at the Config stream. It begins like follows, and goes on forever with various ...

  4. android 通过uri获取bitmap图片并压缩

    很多人在调用图库选择图片时会在onActivityResult中用Media.getBitmap来获取返回的图片,如下: Uri mImageCaptureUri = data.getData(); ...

  5. python字符串格式化方法 format函数的使用

      python从2.6开始支持format,新的更加容易读懂的字符串格式化方法, 从原来的% 模式变成新的可读性更强的 花括号声明{}.用于渲染前的参数引用声明, 花括号里可以用数字代表引用参数的序 ...

  6. Objects and Data Structures

    Date Abstraction Hiding implementation is not just a matter of putting a layer of fucntions between ...

  7. BitMap排序

    问题描述:       BitMap排序思想:             用1bit位标记某个元素对应的值       优点:             效率高,不允许进行比较和移位            ...

  8. Bit-Map

    昨日读July大神<教你如何迅速秒杀掉:99%的海量数据处理面试题>博客,有这么一题与大家分享: 给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断 ...

  9. beej's 网络编程 打包数据pack data

    7.4. Serialization—How to Pack Data It's easy enough to send text data across the network, you're fi ...

随机推荐

  1. 模块_pip、os模块

    一个python文件就是一个模块 1.标准模块 python自带的模块就是标准模块,也就是可以直接import进来的就是标准模块 import json import random import da ...

  2. Shell if条件语句

    1.if条件语句:设定一个条件如果怎么,然后怎么样. (1)-gt大于.-lt小于.-ge大于等于.-le小于等于.-eq等于.-ne不等于. (2)[]内是包括变量时所使用的. (3)-f文件.-n ...

  3. P4312 [COCI 2009] OTOCI / 极地旅行社

    思路 LCT维护和的板子 注意findroot的时候要先access一下,修改点权之前要先splay到根 代码 #include <cstdio> #include <algorit ...

  4. Learning-Python【31】:操作系统基础知识

    什么是操作系统 计算机系统由硬件和软件两部分组成.操作系统(OS,Operating System)是配置在计算机硬件上的第一层软件,是对硬件系统的首次扩充.它在计算机系统中占据了特别重要的地位:而其 ...

  5. 获取添加数据的自增ID

    $id= DB::select("select auto_increment from information_schema.`TABLES` where table_name='stude ...

  6. Spring中ClassPathXmlApplication与FileSystemXmlApplicationContext的区别

    Spring中ClassPathXmlApplication与FileSystemXmlApplicationContext的区别 一.概述 在项目中遇到加载不到Spring配置文件,简单分析后,写此 ...

  7. iconfont作用在css伪类中的写法

    iconfont作用在css伪类中需要注意两点: 1.字体声明(font-family: "iconfont";). 2.把字体写成十六进制的Unicode编码.比如:" ...

  8. Unity---判断某个点是否在摄像机的视景范围内

    using UnityEngine; [RequireComponent(typeof(Camera))] public class VisualDetectionCamera : MonoBehav ...

  9. 第 8 章 容器网络 - 070 - 如何定制 Calico 网络 Policy?

    定制 Calico 网络 Policy Calico 默认的 policy 规则是:容器只能与同一个 calico 网络中的容器通信. Calico 能够让用户定义灵活的 policy 规则,精细化控 ...

  10. Strut2页面传参跳转 --Struts2

    1.本案例借助struts2框架,完成页面传参.跳转功能 2.代码实现 index.jsp: <form action="helloStruts2.action" metho ...