Hide Data into bitmap with ARGB8888 format
将保存重要信息,如银行卡密码的文本文件隐藏到ARGB8888的A通道。
bitmap.h
- #ifndef BMP_H
- #define BMP_H
- #include <fstream>
- #include <string>
- #include <iostream>
- #define DEBUG 0
- #define LOG std::cout
- #define HEX std::hex
- #define DEC std::dec
- #define FLAG_0 (0xFF)
- #define FLAG_1 (0xEE)
- #define FLAG_2 (0xDD)
- #define FLAG_3 (0xCC)
- #define DATA_CODE (0xCC)
- #define BYTE_PER_PIXEL (4)
- #pragma pack(push, 1)
- typedef struct
- {
- uint16_t bfType; // Type of bitmap, in windows, always 'BM'
- uint32_t bfSize; // Size of the bitmap file
- uint16_t bfReserved1; // reserved feild
- uint16_t bfReserved2; // reserved feild
- uint32_t bfOffBits; // the start address of the bitmap data
- }BMP_FILE_HEADER;
- typedef struct
- {
- uint32_t biSize; // size of this struct
- uint32_t biWidth; // image width, unit is pixel
- uint32_t biHeight; // image height, unit is pixel
- uint16_t biPlanes; // alsways 1
- uint16_t biBitCount; // color depth of the image, 1, 4, 8, 16, 24 and 32
- uint32_t biCompression; // compression type, 0=no compress, 1=RLE8 compress
- // 2=RLE4 compress, 3=pixel color mask
- uint32_t biSizeImage; // pixel data size of the image
- uint32_t biXPelsPerMeter; // H resolution, pixel per meter
- uint32_t biYPelsPerMeter; // V resolution, pixel per meter
- uint32_t biClrUsed; // color number that used, 0=all color
- uint32_t biClrImportant; // important color amount, 0=all color important
- }BMP_INFO_HEADER;
- #pragma pacn(pop)
- class Bitmap
- {
- private:
- BMP_FILE_HEADER m_fileHeader;
- BMP_INFO_HEADER m_infoHeader;
- std::string m_bmpPath;
- bool m_parseFlag;
- public:
- Bitmap(std::string path);
- ~Bitmap();
- bool bmpParse();
- uint32_t getBmpSize();
- uint32_t getBmpDataAddr();
- std::string getBmpPath();
- uint32_t getBmpPixelNum();
- };
- class DataHider
- {
- private:
- uint8_t m_flags[4];
- uint8_t m_length[4];
- Bitmap m_bitmapHeader;
- std::string m_dataFilePath;
- bool isAHider();
- uint32_t getFileSize(std::ifstream &in);
- bool readTransByte(std::fstream &file, uint8_t &val, int pos);
- bool writeTransByte(std::fstream &file, uint8_t val, int pos);
- void length2Byte(uint32_t length);
- uint32_t byte2Length();
- public:
- DataHider(std::string dataPath, std::string bmpPath);
- ~DataHider();
- bool doEncode();
- bool doDecode();
- };
- #endif // BMP_H
bitmap.cpp
- #include "bitmap.h"
- Bitmap::Bitmap(std::string path)
- : m_fileHeader(), m_infoHeader(), m_bmpPath(path), m_parseFlag(false)
- {
- }
- Bitmap::~Bitmap()
- {
- }
- bool Bitmap::bmpParse()
- {
- std::ifstream in;
- in.open(m_bmpPath, std::ios::binary);
- in.read((char *)&m_fileHeader, sizeof(m_fileHeader));
- /*char * p = (char *)&m_fileHeader;
- for(uint32_t i=0; i<sizeof(m_fileHeader); ++i)
- {
- in.read(p, 1);
- LOG << HEX << (int)*p << " ";
- ++p;
- }*/
- if( !in.good() )
- {
- LOG << "read bitmap file head error!\n";
- in.close();
- return false;
- }
- in.read((char *)&m_infoHeader, sizeof(m_infoHeader));
- /* LOG << "read bitmap information header!\n";
- p = (char *)&m_infoHeader;
- for(uint32_t i=0; i<sizeof(m_infoHeader); ++i)
- {
- in.read(p, 1);
- LOG << HEX << (int)*p << " ";
- ++p;
- }*/
- if( !in.good() )
- {
- LOG << "read bitmap information header error!\n";
- in.close();
- return false;
- }
- in.close();
- m_parseFlag = true;
- #if 1 == DEBUG
- LOG << "Bitmap file header:"
- << "\nbfType: " << HEX << (int)m_fileHeader.bfType
- << "\nbfSize: " << (int)m_fileHeader.bfSize
- << "\nbfReserved1: " << (int)m_fileHeader.bfReserved1
- << "\nbfReserved2: " << (int)m_fileHeader.bfReserved2
- << "\nbfOffBits: " << (int)m_fileHeader.bfOffBits
- << "\nBitmap information header:"
- << "\nbiSize: " << (int)m_infoHeader.biSize << DEC << "\n";
- #endif
- return true;
- }
- uint32_t Bitmap::getBmpSize()
- {
- if(!m_parseFlag)
- {
- LOG << "please do bitmap parse first!\n";
- }
- return m_fileHeader.bfSize;
- }
- std::string Bitmap::getBmpPath()
- {
- return m_bmpPath;
- }
- uint32_t Bitmap::getBmpDataAddr()
- {
- if(!m_parseFlag)
- {
- LOG << "please do bitmap parse first!\n";
- }
- return m_fileHeader.bfOffBits;
- }
- uint32_t Bitmap::getBmpPixelNum()
- {
- return m_infoHeader.biWidth * m_infoHeader.biHeight;
- }
- DataHider::DataHider(std::string dataPath, std::string bmpPath)
- : m_bitmapHeader(bmpPath), m_dataFilePath(dataPath)
- {
- }
- DataHider::~DataHider()
- {
- }
- bool DataHider::isAHider()
- {
- return (m_flags[0] == FLAG_0) &
- (m_flags[1] == FLAG_1) &
- (m_flags[2] == FLAG_2) &
- (m_flags[3] == FLAG_3);
- }
- uint32_t DataHider::getFileSize(std::ifstream &in)
- {
- if(!in.good())
- {
- LOG << "the data file has some error.\n";
- return false;
- }
- uint32_t pos = in.tellg();
- in.seekg(0, std::ios_base::end);
- uint32_t size = in.tellg();
- in.seekg(pos, std::ios_base::beg);
- return size;
- }
- bool DataHider::readTransByte(std::fstream &file, uint8_t &val, int pos)
- {
- file.seekg(m_bitmapHeader.getBmpDataAddr()+BYTE_PER_PIXEL*pos, std::ios_base::beg);
- #if DEBUG == 1
- LOG << "pos " << HEX << m_bitmapHeader.getBmpDataAddr()+BYTE_PER_PIXEL*pos << "\n";
- #endif
- file.read((char *)&val, 1);
- return file.good();
- }
- bool DataHider::writeTransByte(std::fstream &file, uint8_t val, int pos)
- {
- file.seekp(m_bitmapHeader.getBmpDataAddr()+BYTE_PER_PIXEL*pos, std::ios_base::beg);
- file.write((char *)&val, 1);
- return file.good();
- }
- void DataHider::length2Byte(uint32_t length)
- {
- for(uint32_t i=0; i<4; ++i)
- m_length[i] = (uint8_t)(length >> (i*8)) & 0xFF;
- #if DEBUG == 1
- LOG << "length: " << length << "\n"
- << (int)m_length[0] << " "
- << (int)m_length[1] << " "
- << (int)m_length[2] << " "
- << (int)m_length[3] << "\n";
- #endif
- }
- uint32_t DataHider::byte2Length()
- {
- uint32_t length = 0;
- uint32_t temp;
- for(uint32_t i=0; i<4; ++i)
- {
- temp = m_length[i];
- #if DEBUG == 1
- LOG << "temp: " << temp << "\n";
- #endif
- temp <<= (i*8);
- #if DEBUG == 1
- LOG << "temp: " << temp << "\n";
- #endif
- length += temp;
- }
- #if DEBUG == 1
- LOG << "length: " << length << "\n";
- #endif
- return length;
- }
- bool DataHider::doEncode()
- {
- m_bitmapHeader.bmpParse();
- std::ifstream dataFile;
- dataFile.open(m_dataFilePath, std::ios::binary);
- if(!dataFile.good())
- {
- LOG << "open " << m_dataFilePath << " failed!\n";
- return false;
- }
- uint32_t dataSize = getFileSize(dataFile);
- if(dataSize > m_bitmapHeader.getBmpPixelNum() + 8) // flag size add length size
- {
- LOG << "data is too big to save into the bitmap!\n";
- dataFile.close();
- return false;
- }
- std::fstream bmpFile;
- bmpFile.open(m_bitmapHeader.getBmpPath(), std::ios_base::binary|
- std::ios_base::out|std::ios_base::in);
- // |std::ios_base::ate|std::ios_base::app
- if(!bmpFile.good())
- {
- LOG << "open " << m_bitmapHeader.getBmpPath() << " failed!\n";
- dataFile.close();
- return false;
- }
- dataFile.seekg(0, std::ios_base::beg);
- // flags
- m_flags[0] = FLAG_0;
- m_flags[1] = FLAG_1;
- m_flags[2] = FLAG_2;
- m_flags[3] = FLAG_3;
- for(uint32_t i=0; i<4; ++i)
- writeTransByte(bmpFile, m_flags[i], i);
- // length
- length2Byte(dataSize);
- for(uint32_t i=0; i<4; ++i)
- writeTransByte(bmpFile, m_length[i], i+4);
- // pos start at the 8th pixel
- int pos = 0;
- uint8_t data;
- while(pos < dataSize)
- {
- dataFile.read((char *)&data, 1);
- #if DEBUG == 1
- LOG << HEX << (int)data << " ";
- #endif
- data ^= DATA_CODE;
- writeTransByte(bmpFile, data, pos+8);
- ++pos;
- }
- bmpFile.close();
- dataFile.close();
- return true;
- }
- bool DataHider::doDecode()
- {
- m_bitmapHeader.bmpParse();
- std::fstream bmpFile;
- bmpFile.open(m_bitmapHeader.getBmpPath(), std::ios_base::binary|std::ios_base::in);
- if(!bmpFile.good())
- {
- LOG << "open " << m_bitmapHeader.getBmpPath() << " failed!\n";
- return false;
- }
- bmpFile.seekg(0, std::ios_base::beg);
- // flags
- for(uint32_t i=0; i<4; ++i)
- {
- readTransByte(bmpFile, m_flags[i], i);
- #if DEBUG
- LOG << HEX << (int)m_flags[i] << " ";
- #endif
- }
- if( !isAHider() )
- {
- LOG << "this bitmap is not a hider file!\n";
- bmpFile.close();
- return false;
- }
- // length
- for(uint32_t i=0; i<4; ++i)
- readTransByte(bmpFile, m_length[i], i+4);
- #if DEBUG == 1
- LOG << (int)m_length[0] << " "
- << (int)m_length[1] << " "
- << (int)m_length[2] << " "
- << (int)m_length[3] << "\n";
- #endif
- uint32_t dataSize = byte2Length();
- std::ofstream dataFile;
- dataFile.open(m_dataFilePath, std::ios::binary);
- if(!dataFile.good())
- {
- LOG << "open " << m_dataFilePath << " failed!\n";
- bmpFile.close();
- return false;
- }
- // pos start at the 8th pixel
- int pos = 0;
- uint8_t data;
- while(pos < dataSize)
- {
- readTransByte(bmpFile, data, pos+8);
- data ^= DATA_CODE;
- dataFile.write((char *)&data, 1);
- ++pos;
- }
- bmpFile.close();
- dataFile.close();
- return true;
- }
main.cpp
- #include <iostream>
- #include "bitmap.h"
- using namespace std;
- int main(int argc, char **argv)
- {
- cout << "Hello world!" << endl;
- if(argc < 4)
- {
- cout << "please type the right command!\n"
- << "DataHider encode ./data.txt ./ARGB8888.bmp\n"
- << "or DataHider decode ./data_out.txt ./ARGB8888.bmp\n";
- return -1;
- }
- string mode = argv[1];
- string dataFile = argv[2];
- string bmpFile = argv[3];
- if(mode == "encode")
- {
- cout << "encoder\n";
- DataHider encoder(dataFile, bmpFile);
- encoder.doEncode();
- }
- else if(mode == "decode")
- {
- cout << "decoder\n";
- DataHider decoder(dataFile, bmpFile);
- decoder.doDecode();
- }
- return 0;
- }
Hide Data into bitmap with ARGB8888 format的更多相关文章
- [Data Structure] Bit-map空间压缩和快速排序去重
Bit-map是一种很巧妙的数据存储结构.所谓的Bit-map就是用一个bit位来标记某个元素对应的Value,而Key即是该元素.由于采用了Bit为单位来存储数据,可以大大节省存储空间.Bit-ma ...
- 转:Hide data inside pointers(在指针中隐藏数据)
该文介绍了如何使用指针中一些未使用的位来隐藏一些数据. When we write C code, pointers are everywhere. We can make a little extr ...
- 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 ...
- android 通过uri获取bitmap图片并压缩
很多人在调用图库选择图片时会在onActivityResult中用Media.getBitmap来获取返回的图片,如下: Uri mImageCaptureUri = data.getData(); ...
- python字符串格式化方法 format函数的使用
python从2.6开始支持format,新的更加容易读懂的字符串格式化方法, 从原来的% 模式变成新的可读性更强的 花括号声明{}.用于渲染前的参数引用声明, 花括号里可以用数字代表引用参数的序 ...
- Objects and Data Structures
Date Abstraction Hiding implementation is not just a matter of putting a layer of fucntions between ...
- BitMap排序
问题描述: BitMap排序思想: 用1bit位标记某个元素对应的值 优点: 效率高,不允许进行比较和移位 ...
- Bit-Map
昨日读July大神<教你如何迅速秒杀掉:99%的海量数据处理面试题>博客,有这么一题与大家分享: 给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断 ...
- 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 ...
随机推荐
- 模块_pip、os模块
一个python文件就是一个模块 1.标准模块 python自带的模块就是标准模块,也就是可以直接import进来的就是标准模块 import json import random import da ...
- Shell if条件语句
1.if条件语句:设定一个条件如果怎么,然后怎么样. (1)-gt大于.-lt小于.-ge大于等于.-le小于等于.-eq等于.-ne不等于. (2)[]内是包括变量时所使用的. (3)-f文件.-n ...
- P4312 [COCI 2009] OTOCI / 极地旅行社
思路 LCT维护和的板子 注意findroot的时候要先access一下,修改点权之前要先splay到根 代码 #include <cstdio> #include <algorit ...
- Learning-Python【31】:操作系统基础知识
什么是操作系统 计算机系统由硬件和软件两部分组成.操作系统(OS,Operating System)是配置在计算机硬件上的第一层软件,是对硬件系统的首次扩充.它在计算机系统中占据了特别重要的地位:而其 ...
- 获取添加数据的自增ID
$id= DB::select("select auto_increment from information_schema.`TABLES` where table_name='stude ...
- Spring中ClassPathXmlApplication与FileSystemXmlApplicationContext的区别
Spring中ClassPathXmlApplication与FileSystemXmlApplicationContext的区别 一.概述 在项目中遇到加载不到Spring配置文件,简单分析后,写此 ...
- iconfont作用在css伪类中的写法
iconfont作用在css伪类中需要注意两点: 1.字体声明(font-family: "iconfont";). 2.把字体写成十六进制的Unicode编码.比如:" ...
- Unity---判断某个点是否在摄像机的视景范围内
using UnityEngine; [RequireComponent(typeof(Camera))] public class VisualDetectionCamera : MonoBehav ...
- 第 8 章 容器网络 - 070 - 如何定制 Calico 网络 Policy?
定制 Calico 网络 Policy Calico 默认的 policy 规则是:容器只能与同一个 calico 网络中的容器通信. Calico 能够让用户定义灵活的 policy 规则,精细化控 ...
- Strut2页面传参跳转 --Struts2
1.本案例借助struts2框架,完成页面传参.跳转功能 2.代码实现 index.jsp: <form action="helloStruts2.action" metho ...