⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 基于BMP图像的信息隐藏
💻 CPP
📖 第 1 页 / 共 4 页
字号:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

/************************************\ 
* B L I N D S I D E * 
* * 
* Image stego/crypto tool, please * 
* see http://www.blindside.co.uk * 
* * 
* Compile with GCC or equiv ANSI C * 
* * 
* John Collomosse (mapjpc@bath.ac.uk)* 
* Freeware/public domain * 
* * 
\************************************/ 

#define HEAP_UNITSIZE (102400) 
#define HEAP_INITUNITS (1) 
#define LOOKUP_INITLEN (2048) 
#define FALSE (0) 
#define TRUE (-1) 
#define PATH_SEP ('\\') /* OS Specific Path Seperator */ 
#define BANNER ("BlindSide BMP Cryptographic Tool - (c) John Collomosse 2000\nRelease v0.9. All Rights Reserved, contact: ma7jpc@bath.ac.uk\n\n") 
#define THIS_PROTO_VER (1) 

/* Heap Structure (memory storage class for uchars) */ 
typedef struct heapstruct { 
unsigned int heapunits; /* Heap size to nearest 'unit' */ 
unsigned char *dataspace; /* Dataspace where data stored */ 
unsigned char *nextchar; /* Pointer to end of dataspace */ 
unsigned long heaplen; /* Length of data in heap */ 
} HEAP; 

typedef struct lookupstruct { 
unsigned long int* dataspace; 
unsigned long int currentlen; 
unsigned long int curitem; 
} LOOKUP; 

/* Bitmap Structure */ 
typedef struct bmpstruct { 
char* signature; //图像格式标识
long filesize; //图像文件大小
long x_size; //图像的宽度(以像素为单位)
long y_size; //图像的高度(以像素为单位)
int bitplanes; //图像色彩平面数,固定为1;
int bpp; //图像的垂直分辨率
long compression; 
long compresssize; 
long x_pix_per_metre; 
long y_pix_per_metre; 
long colours; 
long cols_important; //图像中重要的色彩数目
HEAP* palette; 
HEAP* raster; 
} BITMAP; 

typedef struct pixstruct { 
unsigned char red; 
unsigned char green; 
unsigned char blue; 
} PIXEL; 

/* Function prototypes */ 
int initialiseHeap (HEAP*); 
int expandHeap (int, HEAP*); 
void removeHeap (HEAP*); 
int putToHeap (unsigned char,HEAP*); 
int streamFileToHeap (FILE*, HEAP*); 
int readBitmapFile (FILE*, BITMAP*); 
void promoteTo24 (BITMAP*, BITMAP*); 
unsigned long resolveMaxEncode (BITMAP*, LOOKUP*); 
void writeBitmapFile (FILE*, BITMAP*); 
unsigned int biggest_of_3 (unsigned int,unsigned int,unsigned int); 
void longToStream (FILE*,unsigned long int); 
unsigned long streamToLong (FILE*); 
void process24gotpixel (unsigned char, unsigned char*,HEAP*); 
unsigned int calcEOLpad (int, long); 
PIXEL getIndexedPixel (unsigned long int, BITMAP*); 
void encodeData (BITMAP*, HEAP*, LOOKUP*); 
void setIndexedPixel (unsigned long int, BITMAP*, PIXEL); 
unsigned char getNextHeapBit (unsigned long int, int, HEAP*); 
int decodeData (BITMAP*, HEAP*); 
//void cryptoData (HEAP* data, unsigned char* key); 
unsigned char xor (unsigned char, unsigned char); 
int rotl4 (int); 
int hash_func (unsigned char*); 
int pow (int,int); 
int stricmp (const char*, const char*); 
int formatDataspace (BITMAP*, HEAP*); 
void dumpFileDirectory (HEAP*); 
void dumpFileStats (BITMAP*, HEAP*); 
void addFileToArchive (HEAP*, FILE*, char*); 
int checkExists (char*); 
int extractFile (HEAP*, char*); 
void flattenBitmap (BITMAP*, LOOKUP*); 

int main (int argc, char** argv) { 
int mode; 
FILE* bitmap_handle=NULL; //指向BMP图片
FILE* plaintext_handle=NULL; //指向普通的需要隐藏的文本文件
FILE* outfile_handle=NULL; //输出文件
BITMAP* BMPsource=NULL; //结构体
BITMAP* BMPworking=NULL; //结构体
HEAP* filespace=NULL; 
LOOKUP* hotspots; 
unsigned long int i; 
//int isencrypted=FALSE; 
//char password[130]; 

//printf(BANNER); 

mode=0; 
if (argc >=2) { 
/* deduce mode of operation */ 
if (stricmp(argv[1],"-A")==0) 
mode=1; 
if (stricmp(argv[1],"-X")==0) 
mode=2; 
if (stricmp(argv[1],"-C")==0) 
mode=3; 
if (stricmp(argv[1],"-L")==0) 
mode=4; 
} 

if (mode==0 || (mode==1 && (argc!=5 && argc!=6)) || (mode==2 && (argc!=3 && argc!=4 && argc!=5)) || (mode==3 && argc!=3) || (mode==4 && argc!=3)) { 
printf("USAGE: BSIDE < option > < filenames - see below >\n\n"); 
printf("Option Description\n"); 
printf("~~~~~~ ~~~~~~~~~~~\n"); 
printf(" -A Add a file into image, need to specify files as follows\n"); 
printf(" BSIDE -A < BMP file > < plaintext file > < result BMP file > [password]\n\n"); 
printf(" -X eXtract file(s) from image, need to specify files as follows\n"); 
printf(" BSIDE -X < BMP file > [file to extract] [password if needed]\n\n"); 
printf(" -C Calculate data storage statistics of a bitmap\n"); 
printf(" BSIDE -C < BMP file >\n\n"); 
printf(" -L List files stored within a bitmap\n"); 
printf(" BSIDE -L < BMP file >\n\n"); 
printf("Please note that wildcards are NOT currently supported\n\n"); 
printf("BlindSide is (c) John Collomosse 2000, All Rights Reserved\nComments/suggestions to ma7jpc@bath.ac.uk, updates see www.blindside.co.uk\n"); 
exit(1); 
} 

/* Read Password off of command line */ 

for (i=0; i< 129; i++) 
password[i]='\0'; 
if ((argc==6 && mode==1) || (argc==5 && mode==2)) { 
isencrypted=TRUE; 
for (i=0; i< 129; i++) { 
password[i]=argv[6-mode][i]; 
if (argv[6-mode][i]=='\0') 
break; 
} 
password[129]='\0'; 
} 


/* Open all necessary files */ 
bitmap_handle=fopen(argv[2],"rb"); //打开载体图像
if (mode==1) 
plaintext_handle=fopen(argv[3],"rb"); //打开密码文件

if (bitmap_handle==NULL) { 
printf("FATAL: Could not open bitmap %s!\n",argv[2]); 
exit(2); 
} 
if (plaintext_handle==NULL && mode==1) { 
printf("FATAL: Could not open plaintext %s!\n",argv[3]); 
exit(3); 
} 

/* Read source bitmap (this must be done for every command line variation) */ 
printf("? Reading bitmap file...."); 
BMPsource=(BITMAP*)calloc(1,sizeof(BITMAP)); 
BMPsource->palette=(HEAP*)calloc(1,sizeof(HEAP)); 
BMPsource->raster=(HEAP*)calloc(1,sizeof(HEAP)); 
initialiseHeap(BMPsource->palette); 
initialiseHeap(BMPsource->raster); 
if (!readBitmapFile(bitmap_handle,BMPsource)) { 
printf("ERROR\n\nFATAL: Out of memory, while reading bitmap file\n"); 
exit(4); 
} 
printf("OK\n"); 


/* Analyse Bitmap */ 
if (stricmp("BM",BMPsource->signature) || BMPsource->bitplanes!=1) { 
printf("FATAL: Not a valid bitmap file\n"); 
exit(5); 
} 
if (BMPsource->compression!=0) { 
printf("FATAL: BlindSide cannot work with compressed bitmaps yet\n"); 
exit(6); 
} 
if (BMPsource->bpp==1) { 
printf("FATAL: BlindSide can't work with monochrome images, as it is the colours\nwithin the image itself that are used to hide files within a bitmap.\nYou can only use bitmaps of greater colour depth (16c, 256c, 16Mc)\n"); 
exit(8); 
} 
if (BMPsource->bpp!=4 && BMPsource->bpp!=8 && BMPsource->bpp!=24) { 
printf("FATAL: Can't work with a bitmap with %d bits per pixel\n\nTry saving the bitmap into a different bit depth in a graphics package.\n",BMPsource->bpp); 
exit(8); 
} 
printf("? Image is %ld bytes (%ldx%ld), %d bits/pixel\n",BMPsource->filesize,BMPsource->x_size,BMPsource->y_size,BMPsource->bpp); 

/* Colour depth increase if need be */ 
if (BMPsource->bpp< 24) { 
printf("? Increasing Colour Depth to 16M colours (24bpp)..."); 
BMPworking=(BITMAP*)calloc(1,sizeof(BITMAP)); 
if (BMPworking==NULL) { 
printf("\n\nFATAL: Out of memory while increasing colour depth"); 
exit(4); 
} 
BMPworking->palette=(HEAP*)calloc(1,sizeof(HEAP)); 
BMPworking->raster=(HEAP*)calloc(1,sizeof(HEAP)); 
if (BMPworking->palette==NULL || BMPworking->raster==NULL) { 
printf("\n\nFATAL: Out of memory while increasing colour depth"); 
exit(4); 
} 
if (!initialiseHeap(BMPworking->palette) || !initialiseHeap(BMPworking->raster)) { 
printf("\n\nFATAL: Out of memory while increasing colour depth"); 
exit(4); 
} 
/* Do the promote to 24bpp */ 
promoteTo24(BMPsource, BMPworking); 
/* cleanup source */ 
removeHeap(BMPsource->palette); 
removeHeap(BMPsource->raster); 
free(BMPsource); 
BMPsource=NULL; 
printf("OK\n"); 
} 
else { 
/* Source was fine -> already 24 bpp */ 
BMPworking=BMPsource; 
BMPsource=NULL; 
} 

/* Prepare BS dataspace */ 
printf("? Analysing Data Patterns...."); 
filespace=(HEAP*)calloc(1,sizeof(HEAP)); 
initialiseHeap(filespace); 
switch (decodeData(BMPworking,filespace)) { 
case 0: printf("OK\n"); 
break; 
case 1: removeHeap(filespace); 
initialiseHeap(filespace); 
if (mode==2 || mode==4) { 
printf("ERROR\n\nFATAL: File does not contain any BlindSide hidden data\n"); 
exit(4); 
} 
printf("OK\n"); 
if (mode==1) { 
printf("? Creating New Archive...."); 
if (formatDataspace(BMPworking, filespace)) 
printf("OK\n"); 
else { 
printf("ERROR\n\nFATAL: There isn't enough space in the bitmap to hold any Blindside hidden data\n"); 
exit(4); 
} 
} 
break; 
case 2: printf("\nFATAL: Out of memory while analysing bitmap\n"); 
exit(4); 
break; 
case 3: printf("\nFATAL: Bitmap was encoded using a higher version of BlindSide than this one\n"); 
exit(4); 
break; 
} 

/* At this point 'filespace' is always a working BS archive (although it may be one with no files contained) */ 
/* In case of Mode 3 it MAY NOT be the case that filespace is archive - it may be empty heap */ 

/* Decrypt if necessary */ 
if (filespace->heaplen!=0) { 
if (*(filespace->dataspace+1)=='E') { 
/* decrypt */ 
if (strcmp(password,"")==0) { 
/* get pword */ 
printf("\nData is encrypted, please enter password: "); 
scanf("%s",password); 
printf("\n"); 
} 
/*printf("? Decrypting Data...."); 
cryptoData(filespace,password); 
if (*(filespace->dataspace+7)=='O' && *(filespace->dataspace+8)=='K') { 
printf("OK\n"); 
isencrypted=TRUE; 
} 
else { 
printf("ERROR\n\nFATAL: Incorrect password\n"); 
exit(9); 
} 
*/
} 
} 

/* Do whichever of the operations was requested */ 
switch (mode) { 
case 1: printf("\n"); 
for (i=strlen(argv[3]); i >0; i--) { 
if (argv[3][i]==PATH_SEP) 
break; 
} 
if (i!=0 || (argv[3][0]==PATH_SEP)) 
i++; 
addFileToArchive(filespace,plaintext_handle,&(argv[3][i])); 
printf("\n"); 
break; 
case 2: printf("\n"); 
if (argc >=3) 
extractFile(filespace,argv[3]); 
else 
extractFile(filespace,NULL); 
break; 
case 3: dumpFileStats(BMPworking, filespace); 
break; 
case 4: dumpFileDirectory(filespace); 
break; 
} 


/* Output to disk */ 
/* If we were in ADD mode, write the bitmap out (Xtract, Calc, and List are READ ONLY) */ 
if (mode==1) { 
/* close plaintext */ 
fclose(plaintext_handle); 
if (isencrypted==TRUE) { 
printf("? Encrypting Data...."); 
//cryptoData(filespace,password); 
printf("OK\n"); 
} 
printf("? Encoding Data...."); 
hotspots=(LOOKUP*)calloc(1,sizeof(LOOKUP)); 
if (hotspots==NULL) { 
printf("ERROR\n\nOut of memory\n"); 
exit(4); 
} 
hotspots->dataspace=(unsigned long int*)calloc(LOOKUP_INITLEN,sizeof(unsigned long int)); 
if (hotspots==NULL) { 
printf("ERROR\n\nOut of memory\n"); 
exit (4); 
} 
hotspots->currentlen=LOOKUP_INITLEN; 
flattenBitmap(BMPworking,hotspots); 
encodeData(BMPworking,filespace,hotspots); 
printf("OK\n"); 
printf("? Writing result to %s....",argv[4]); 
outfile_handle=fopen(argv[4],"wb"); 
writeBitmapFile(outfile_handle, BMPworking); 
fclose(outfile_handle); 
printf("OK\n"); 
} 


/* Cleaup and exit */ 
printf("\nDone!\n"); 
removeHeap(filespace); 
free(filespace); 
removeHeap(BMPworking->palette); 
free(BMPworking->palette); 
removeHeap(BMPworking->raster); 
free(BMPworking->raster); 
free(BMPworking); 
return(0); 
} 

/***************************** HEAP MANAGEMENT ***********************/ 
int initialiseHeap(HEAP* heap) { 
heap->dataspace=NULL; 
heap->heapunits=0; 
heap->nextchar=NULL; 
heap->heaplen=0; 

heap->dataspace=(unsigned char*)calloc(HEAP_INITUNITS,HEAP_UNITSIZE*sizeof(unsigned char)); 
if (heap->dataspace==NULL) 
return FALSE; 
else { 
heap->heapunits=HEAP_INITUNITS; 
heap->nextchar=heap->dataspace; 
return TRUE; 
} 
} 

int expandHeap(int newunits, HEAP* heap) { 
if (newunits> heap->heapunits) { 
unsigned char* tmpheap; 
int i; 

tmpheap=heap->dataspace; 
heap->dataspace=(unsigned char*)calloc(newunits,HEAP_UNITSIZE*sizeof(unsigned char)); 
if (heap->dataspace==NULL) { 
heap->dataspace=tmpheap; 
return FALSE; 
} 
else { 
for (i=0; i< heap->heapunits*HEAP_UNITSIZE; i++) 
heap->dataspace[i]=tmpheap[i]; 
free(tmpheap); 
heap->nextchar=(heap->dataspace)+(heap->heapunits*HEAP_UNITSIZE); 
heap->heapunits=newunits; 
} 
} 
return TRUE; 
} 

void removeHeap(HEAP* heap) { 
if (heap->dataspace!=NULL) { 
free (heap->dataspace); 
heap->heapunits=0; 
heap->dataspace=NULL; 
heap->nextchar=NULL; 
heap->heaplen=0; 
} 
} 

int streamFileToHeap(FILE* infile, HEAP* heap) { 
unsigned char readchar; 

while (fscanf(infile,"%c",&readchar) >0) { 
if (!putToHeap(readchar,heap)) 
return FALSE; 
} 

return TRUE; 
} 

int putToHeap(unsigned char data, HEAP* heap) { 

unsigned long hopeful_pos=heap->heaplen; 
unsigned long current_pos=(heap->heapunits*HEAP_UNITSIZE); 


if (hopeful_pos >= current_pos) { 
int discrep=(int)hopeful_pos/HEAP_UNITSIZE; 
discrep++; 
if (!expandHeap(discrep, heap)) { 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -