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

📄 locku.cpp

📁 将其他文件隐藏在BMP图像中!好
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
本着知识共享的原则,我把程序的源代码也放上来,
希望有人能完善它。允许在遵循 GPL 准则的基础上对程序进行修改和重新发布!
****************************************************************************/
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Locku.h"
#include "Password.h"
#include "Help.h"
#include "NewFolder.h"  
//#include "NewFile.h"
#include <dos.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;
//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
//加密程序初始化
//---------------------------------------------------------------------------
void __fastcall TMainForm::Initialize()
{
   //显示当前状态信息
   StatusBar1->Panels->Items[0]->Text="准备执行";
   Stop=false;
   Timer1->Enabled=true;
   //初始化加密字
   CoolWordLen=8;
   CoolWord=new char[CoolWordLen+1];
   strcpy(CoolWord,"$#@%!&*^");
   //修正了密码为空死循环的BUG,并增加了加密的安全性,又改回来了,嘻嘻
   PasswordLen=PasswordDlg->Password->Text.Length();
   if(PasswordLen<8) PasswordLen=8;
   Password=new char[PasswordLen+1];
   strcpy(Password,"VRW&^#T&^");
   strcpy(Password,PasswordDlg->Password->Text.c_str());
   for(int i=0;i<PasswordLen;i++){
       Password[i]^=CoolWord[i%CoolWordLen];
   }
   //加密字创建结束
   //状态条显示
   StatusBar1->Panels->Items[1]->Text="From:"+OriginFileName
        +"("+AnsiString(OriginFileLen/1024)+"KB)";
   StatusBar1->Panels->Items[2]->Text="To:"+ObjectFileName
         +"("+AnsiString(ObjectFileLen/1024)+"KB)";
}
//---------------------------------------------------------------------------
//获得密码
//---------------------------------------------------------------------------
bool __fastcall TMainForm::GetPassword()
{
    AnsiString s;
	PasswordDlg->Label1->Caption="请输入你的密码:";
	do{
    	if(PasswordDlg->ShowModal()==mrCancel){
        	return false;
        }
	}while(PasswordDlg->Password->Text.IsEmpty());
    s=PasswordDlg->Password->Text;
	PasswordDlg->Label1->Caption="确认密码:";
	do{
    	if(PasswordDlg->ShowModal()==mrCancel){
            return false;
        }
	}while(PasswordDlg->Password->Text.IsEmpty());
    if(!(s==PasswordDlg->Password->Text)){
    	MessageDlg("输入的密码不匹配!",mtError,TMsgDlgButtons()<<mbOK,0);
        return false;
	}
    return true;
}
//---------------------------------------------------------------------------
//直接给文件加密
//---------------------------------------------------------------------------
bool __fastcall TMainForm::DirectPut()
{
   //如果文件存在,提示是否替换现有文件
   if(FileExists(ObjectFileName)){
      int Result=MessageDlg("目标文件:\""+ObjectFileName
            +"\"已存在,是否替换现有文件?",mtWarning,
            TMsgDlgButtons()<<mbYes<<mbNo<<mbCancel,0);
      //如果用户按了取消键,返回主窗口
      if(Result==mrCancel) return true;
      else if(Result==mrNo){
         //如果不替换,创建新的文件,提示输入新文件名,默认值为原目标文件前加一下划线
         /*NewFileDlg->NewFile->Text="_"+ExtractFileName(ObjectFileName);
         if(NewFileDlg->ShowModal()==mrOk){
             //如果新建文件确定,目标文件改名为输入的文件名
             ObjectFileName=ExtractFileName(NewFileDlg->NewFile->Text);
         }*/
         ToFile->SetFocus();
         return true;
      }
   }
////////////如果确定密码,开始执行加密程序初始化,否则返回
  //	if(!GetPassword()) return true;
  //打开(创建)文件
   if( (TempFileP=fopen(TempFileName.c_str(),"wb")) == NULL){
       MessageDlg("创建目标文件出错,请检查是否磁盘已满或磁盘写保护!",mtError,TMsgDlgButtons()<<mbOK,0);
       ToFile->SetFocus();
       return true;
   }
/////////////////////////////////////////////////////////////
//确定密码,开始程序初始化
   Initialize();
   Timer1->Enabled=false;
  ///////////初始化完毕,执行加密
/////////////////////////////////////////////////////////////////
   ProgressBar1->Max=OriginFileLen/PasswordLen;
   StatusBar1->Panels->Items[0]->Text="正在执行...";
   //开始执行
   char PassChar;
   char TempChar=fgetc(OriginFileP);//临时字符,为实现循环加密
   int i;//定义循环变量
   while(!feof(OriginFileP)){//如果文件结束退出
       for(i=0;i<PasswordLen;i++){
          PassChar=fgetc(OriginFileP);//读取一个字节
          if(feof(OriginFileP)) break; //如果文件结束,跳出
          else      //否则执行加密算法
          {
              PassChar^=Password[i];
              fputc(PassChar,TempFileP);
           }
       }
       //进度条前进
       ProgressBar1->StepIt();
       Application->ProcessMessages();
       if(Stop) return false;
   }
   fputc(TempChar^Password[i%PasswordLen],TempFileP);
   return false;
}

//---------------------------------------------------------------------------
//直接解密方式
//---------------------------------------------------------------------------

bool __fastcall TMainForm::DirectGet()
{
   //如果文件存在,提示是否替换现有文件
   if(FileExists(ObjectFileName)){
      int Result=MessageDlg("目标文件:\""+ObjectFileName
            +"\"已存在,是否替换现有文件?",mtWarning,
            TMsgDlgButtons()<<mbYes<<mbNo<<mbCancel,0);
      //如果用户按了取消键,返回主窗口
      if(Result==mrCancel) return true;
      else if(Result==mrNo){
         //如果不替换,创建新的文件,提示输入新文件名,默认值为原目标文件前加一下划线
         /*NewFileDlg->NewFile->Text="_"+ExtractFileName(ObjectFileName);
         if(NewFileDlg->ShowModal()==mrOk){
             //如果新建文件确定,目标文件改名为输入的文件名
             ObjectFileName=ExtractFileName(NewFileDlg->NewFile->Text);
         }*/
         ToFile->SetFocus();
         return true;
      }
   }
////////////如果确定密码,开始执行加密程序初始化,否则返回
 //	if(!GetPassword()) return true;
  //打开(创建)文件
   if( (TempFileP=fopen(TempFileName.c_str(),"wb")) == NULL){
       MessageDlg("创建目标文件出错,请检查是否磁盘已满或磁盘写保护!",mtError,TMsgDlgButtons()<<mbOK,0);
       ToFile->SetFocus();
       return true;
   }
/////////////////////////////////////////////////////////////
//确定密码,开始程序初始化
   Initialize();
   Timer1->Enabled=false;
  ///////////初始化完毕,执行加密
/////////////////////////////////////////////////////////////////
   ProgressBar1->Max=OriginFileLen/PasswordLen;
   StatusBar1->Panels->Items[0]->Text="正在执行...";
   //开始执行
   char PassChar[2];
   fputc(PassChar[0],TempFileP);//临时字符,为实现循环加密
   PassChar[1]=fgetc(OriginFileP);
   while(!feof(OriginFileP)){//如果文件结束退出
       for(int i=0;i<PasswordLen;i++){
          PassChar[0]=PassChar[1];
          PassChar[0]^=Password[i];
          PassChar[1]=fgetc(OriginFileP);
          if(feof(OriginFileP)) break; //如果文件结束,跳出
          else      //否则执行加密算法
              fputc(PassChar[0],TempFileP);
       }
       //进度条前进
       ProgressBar1->StepIt();
       Application->ProcessMessages();
       if(Stop) return false;
   }
   rewind(TempFileP);
   fputc(PassChar[0],TempFileP);
   return false;
}
//---------------------------------------------------------------------------
//将文件加密到24位位图
//---------------------------------------------------------------------------
bool __fastcall TMainForm::AddToBmp24()
{
	long pic_offset,bmp_len;
	/*	pic_offset为位图阵列的偏移量,
		OriginFilelen保存了被隐藏文件的长度,
		bmp_len为实际位图阵列的长度	*/
	int i,j=0,tag;	//tag为BMP图像文件的颜色深度,j为取密码字节,i取位图位
	char byte_buf,byte_bufs[8];//读写文件的缓冲区
	char mask[8]={	0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80	};
	//用于将被隐藏文件拆分为位形式的掩码
    //如果文件不存在,返回
    if(!FileExists(ObjectFileName)){
        MessageDlg("目标文件:\""+ObjectFileName+"\"不存在",mtError,
                TMsgDlgButtons()<<mbOK,0);
        return true;
    }
    //打开位图文件
    if( (ObjectFileP=fopen(ObjectFileName.c_str(),"rb") ) == NULL){
       MessageDlg("不能打开目标文件:\""+ObjectFileName+"\"",mtError,
                TMsgDlgButtons()<<mbOK,0);
       ToFile->SetFocus();
       return true;
    }
    ////////////读取位图文件信息文件
    fread(byte_bufs,2,1,ObjectFileP);
    fseek(ObjectFileP,28L,0);
    tag=getw(ObjectFileP);//读取BMP图像颜色深度
    /////////////如果文件不是24位图文件,返回
    if( (byte_bufs[0]!='B') || (byte_bufs[1]!='M') || (tag!=24) ){
        MessageDlg("目标文件:\""+ObjectFileName+
              "\"不是24Bit位图文件",mtError,TMsgDlgButtons()<<mbYes,0);
        return true;
    }
///////////////////////////////////////
//	if(!GetPassword())	return true;
////////////如果确定密码,开始执行加密程序初始化,否则返回
/////////////////////////////////////////////////////////////
//确定密码,开始程序初始化
    if( (TempFileP=fopen(TempFileName.c_str(),"wb") )==NULL){
        MessageDlg("创建临时文件出错,请检查是否磁盘已满或磁盘写保护!",mtError,
                 TMsgDlgButtons()<<mbOK,0);
        return true;
    }
	fseek(ObjectFileP,10L,0);
	fread(&pic_offset,4,1,ObjectFileP);
	bmp_len=ObjectFileLen-pic_offset-1;//计算位图阵列长度
    ///////////如果被加密文件长度大于位图所能装载的最大长度,警告
    if(OriginFileLen>=bmp_len/8-2){
        MessageDlg("待加密文件\""+OriginFileName+"\"太长,无法将其加密到\""
        		+ObjectFileName+"\"",mtError,TMsgDlgButtons()<<mbOK,0);
        FromFile->SetFocus();
        return true;
    }//end if
///////////////////////////////////////////////////////////////
//打开目标文件成功,准备加密
   Initialize();
////////////////////////////////////////////
// 文件指针定位
    char *buff=new char[pic_offset];//文件缓冲区,用来转移图片头信息
    rewind(ObjectFileP);
    fread(buff,pic_offset,1,ObjectFileP);
    fwrite(buff,pic_offset,1,TempFileP);
/*    fseek(TempFileP,2L,0);
    fwrite(&OriginFileLen,4,1,TempFileP);//将被隐藏文件长度写入图像头部偏移2处
	fseek(ObjectFileP,pic_offset,0);//定位读写指针到图像的位图阵列开始处
    fseek(TempFileP,pic_offset,0);*/
    fread(buff,16,1,ObjectFileP);
    for(i=0;i<16;i++){
    	if( OriginFileLen&(1<<i) )buff[i]&=0xfe;
        else buff[i]|=1;
    }
    //fseek(ObjectFileP,-16L,1);
    fwrite(buff,16,1,TempFileP);
    delete []buff;
    buff=new char[1024];//为写图片预留
///////////////////////////////////////////////////////////
   Timer1->Enabled=false;
   ///////////初始化完毕,执行加密
/////////////////////////////////////////////////////////////////
   ProgressBar1->Max=OriginFileLen;
   StatusBar1->Panels->Items[0]->Text="正在执行...";
   //开始执行
	fread(byte_bufs,8,1,ObjectFileP);
   	byte_buf=fgetc(OriginFileP);
	while(!feof(ObjectFileP)&&!feof(OriginFileP))
	{	//拆分被隐藏文件为位形式并覆盖位图阵列每字节的最低位
        byte_buf^=Password[j];
        for(i=0;i<8;i++)
	    {
           	if((byte_buf&mask[i])>>i)byte_bufs[i]|=1;
			else byte_bufs[i]&=0xfe;
		}
		fwrite(byte_bufs,8,1,TempFileP);
		fread(byte_bufs,8,1,ObjectFileP);
     	byte_buf=fgetc(OriginFileP);
   	    ProgressBar1->StepIt();
        j++;
        if(j>=PasswordLen) j=0;
        Application->ProcessMessages();
        if(Stop)return false;
	}//end while
    if(!feof(ObjectFileP)){//如果未到文件尾
    	fseek(ObjectFileP,-8L,1);
	    fread(buff,1024L,1,ObjectFileP);
	    while(!feof(ObjectFileP)){
	    	fwrite(buff,1024,1,TempFileP);
	        fread(buff,1024,1,ObjectFileP);
	    }
    }
    //fseek(ObjectFileP,-1024L,1);修正
    byte_buf=fgetc(ObjectFileP);
    while(!feof(ObjectFileP)){
        fputc(byte_buf,TempFileP);
        byte_buf=fgetc(ObjectFileP);
    }//end while
    delete []buff;
	return false;
}
//---------------------------------------------------------------------------
//从24位位图中提取加密过的文件
//---------------------------------------------------------------------------
bool __fastcall TMainForm::ExtFromBmp24()
{
	long pic_offset,len=0;
	/*	pic_offset为位图阵列的偏移量,
		OriginFilelen保存了被隐藏文件的长度,
		bmp_len为实际位图阵列的长度	*/
	int i,j=0,tag;	//tag为BMP图像文件的颜色深度,如8位和24位等
	char byte_buf,byte_bufs[8];//读写文件的缓冲区
	char mask[8]={	0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80	};
	//用于将被隐藏文件拆分为位形式的掩码
    ////////////读取位图文件信息文件
    fread(byte_bufs,2,1,OriginFileP);
    fseek(OriginFileP,28L,0);
    tag=getw(OriginFileP);//读取BMP图像颜色深度
    /////////////如果文件不是24位图文件,返回
    if( (byte_bufs[0]!='B') || (byte_bufs[1]!='M') || (tag!=24) ){
        MessageDlg("原文件:\""+OriginFileName+
              "\"不是24Bit位图文件",mtError,TMsgDlgButtons()<<mbOK,0);
        return true;
    }
/////////////////////////////////////////////////////////////

   //如果文件存在,提示是否替换现有文件
   if(FileExists(ObjectFileName)){
      int Result=MessageDlg("目标文件:\""+ObjectFileName
            +"\"已存在,是否替换现有文件?",mtWarning,
            TMsgDlgButtons()<<mbYes<<mbNo<<mbCancel,0);
      //如果用户按了取消键,返回主窗口
      if(Result==mrCancel)  return true;
      else if(Result==mrNo){
         //如果不替换,创建新的文件,提示输入新文件名,默认值为原目标文件前加一下划线
         /*NewFileDlg->NewFile->Text="_"+ExtractFileName(ObjectFileName);
         if(NewFileDlg->ShowModal()==mrOk){
             //如果新建文件确定,目标文件改名为输入的文件名
             ObjectFileName=ExtractFileName(NewFileDlg->NewFile->Text);
         }*/
         ToFile->SetFocus();
         return true;
      }
   }
	//打开(创建)文件
   if( (TempFileP=fopen(TempFileName.c_str(),"wb")) == NULL){
       MessageDlg("创建目标文件出错,请检查是否磁盘已满或磁盘写保护",
                  mtError,TMsgDlgButtons()<<mbOK,0);
       ToFile->SetFocus();
       return true;
   }
//打开目标文件成功
/////////////////////////////////////////////////////////////
   //确定密码,开始程序初始化
   Initialize();
////////////////////////////////////////////
   // 文件指针定位
   /*	fseek(OriginFileP,2L,0);
	fread(&ObjectFileLen,4,1,OriginFileP);*///从图像头部偏移2处读取隐藏文件长度*/
	fseek(OriginFileP,10L,0);
	fread(&pic_offset,4,1,OriginFileP);
	fseek(OriginFileP,pic_offset,0);//定位读写指针到图像的位图阵列开始处
    char *buff=new char[16];
    fread(buff,16,1,OriginFileP);
    ObjectFileLen=0;
    for(i=0;i<16;i++){
    	if(!(buff[i]&1))ObjectFileLen|=(1<<i);
    }
    delete []buff;
///////////////////////////////////////////////////////////
   ///////////初始化完毕,执行加密
/////////////////////////////////////////////////////////////////
   Timer1->Enabled=false;
   ProgressBar1->Max=ObjectFileLen;
   StatusBar1->Panels->Items[0]->Text="正在执行...";

⌨️ 快捷键说明

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