c言語 シーザー暗号による画像の暗号化プログラム編3
c言語 シーザー暗号による画像の暗号化プログラム3
画像の暗号化プログラムのソースコード
このソースコードは素人が自己流で、あり合わせの知識で作ったものですから問題点はたくさんありますが、一応画像ファイルを暗号化することができます。
このプログラムは、画像を2つのtxtファイルに変換して、そのtxtファイルをシーザー暗号化するプログラムです。
#include<stdio.h> #include<stdlib.h> int main(void) { while(1){ int a; printf("1変換2還元"); scanf("%d",&a); unsigned char header[54]; unsigned char screen[640][480][3]; if(a==1) { char fnn[16]; char fnnn[32]; printf("暗号化したい画像名を入力して下さい"); FILE*fpo; FILE*fp; scanf("%s",fnn); fpo=fopen("itizi.txt","w"); fprintf(fpo,"%s",fnn); fclose(fpo); fpo=fopen("itizi.txt","a"); fprintf(fpo,".txt"); fclose(fpo); fp=fopen(fnn,"rb"); if(fp==NULL) {printf("入力したファイルはありません");} else { fread(header,1,54,fp); fread(screen,1,640*480*3,fp); FILE*sss; FILE*ss; sss=fopen("111.txt","wb"); fwrite(header,1,54,sss); ss=fopen("222.txt","wb"); fwrite(screen,1,640*480*3,ss); fclose(fp); fclose(sss); fclose(ss); printf("変換前のの画像 を削除しますか1yes2no"); int sll; scanf("%d",&sll); if(sll==1) { (remove(fnn)==0);} {FILE*on,*to,*ow,*wo; int v; int k; printf("パスワードを入力してください4桁以内のすうちのみ"); scanf("%d",&k); on=fopen("111.txt","rb"); to=fopen("222.txt","rb"); ow=fopen("b111.txt","wb"); wo=fopen("b222.txt","wb"); while((v=getc(on))!=EOF) {putc(v+k,ow);} while((v=getc(to))!=EOF) {putc(v+k,wo);} fclose(to); fclose(on); fclose(wo); fclose(ow); char l[]="111.txt"; (remove(l)==0); char ttt[]="222.txt"; (remove(ttt)==0); const char*b111; const char*fnno; const char*b222; const char*fnnnn; char b111[]="b111.txt"; char b222[]="b222.txt"; char fnno[16]; char fnnnn[32]; /*ファイル名保存*/ FILE*fn; fpo=fopen("itizi.txt","r"); fread(fnno,1,16,fpo); fclose(fpo); fn=fopen(fnno,"r"); if(fn==NULL){ fclose(fn); if(rename(b111,fnno)==0); {printf("\n処理完了\n\n");} } char mkml[]="2.txt"; /*ファイル名保存*/ fpo=fopen("itizi.txt","a"); fwrite(mkml,1,5,fpo); fclose(fpo); fpo=fopen("itizi.txt","r"); fread(fnnnn,1,32,fpo); fclose(fpo); if(rename(b222,fnnnn)==0); { printf("処理完了\n");} /*itizi消し*/ char cpc[]="itizi.txt"; if(remove(cpc)==0){printf("処理完了\n");} }}} if(a==2) { char subto[]="2.txt"; char fnn[64]; char fnnn[64]; printf("ファイル名を入力してください"); scanf("%s",fnn); FILE*txx; txx=fopen("txx.txt","w"); fprintf(txx,"%s%s",fnn,subto); fclose(txx); txx=fopen("txx.txt","r"); fscanf(txx,"%s",fnnn); fclose(txx); /*end*/ FILE*on,*to,*th,*f,*sub,*subs; int v; int k; printf("パスワードを入力してください"); scanf("%d",&k); on=fopen("111.txt","wb"); to=fopen("222.txt","wb"); th=fopen(fnn,"rb");//fnn.txt f=fopen(fnnn,"rb");//fnn.txt2.txt sub=fopen("111su.txt","wb"); subs=fopen("222su.txt","wb"); fread(header,1,54,th); fread(screen,1,640*480*3,f); fwrite(header,1,54,sub); fwrite(screen,1,640*480*3,subs); fclose(sub); fclose(subs); fclose(th); fclose(f); th=fopen(fnn,"rb"); f=fopen(fnnn,"rb"); while((v=getc(th))!=EOF) {putc(v-k,on);} while((v=getc(f))!=EOF) {putc(v-k,to);} fclose(on); fclose(to); fclose(th); fclose(f); on=fopen("111.txt","rb"); to=fopen("222.txt","rb"); fread(header,1,54,on); fread(screen,1,640*480*3,to); fclose(to); fclose(on); char fnf[8]; FILE*fp; printf("画像の名前を入力してくださいファイル名の最後には必ず.bmpや、.jpgなどをつけてください"); scanf("%s",fnf); fp=fopen(fnf,"rb"); fclose(fp); if(fp==NULL) { fp=fopen(fnf,"wb"); fwrite(header,1,54,fp); fwrite(screen,1,640*480*3,fp); fclose(fp); printf("余分なファイル類を消しますか1yes2no"); } else{return 0;} scanf("%d",&k); if(k==1) { char l[]="111.txt"; (remove(l)==0); char ttt[]="222.txt"; (remove(ttt)==0); (remove(fnn)==0); (remove(fnnn)==0); } else{printf("\n\n バックアップの111su.txt,222su.txtが存在します。画像ファイルに戻すなら、名前をb111.txt,b222.txtにして[半角入力]、再び「2.還元」を選択してください。不必要なら削除してください。削除しますか? \n\n1、削除する2、削除しない"); int r; scanf("%d",&r); if(r==1){ printf("111suと222suを削除しました"); char k[]="111su.txt"; (remove(k)==0); char o[]="222su.txt"; (remove(o)==0); } if(r==2){return 0;} return 0; }/*else */ }/*a==2*/ printf("ESCkeyで終了\n\n"); int jjj=0; jjj=getch(); if(jjj==27) break; }/*while*/ }/*intmainvoid*/
© 2014 idoushiki
・免責事項
プログラムの著作権は移動式(作者)にあります。
当ブログのソースコードを利用した事によるいかなる損害も作者(移動式)は一切の責任を負いません。自己の責任の上で使用して下さい。
解説
・ファイルの存在の有無を確認する部分
scanf("%s",fnn); fpo=fopen("itizi.txt","w"); fprintf(fpo,"%s",fnn); fclose(fpo); fpo=fopen("itizi.txt","a"); fprintf(fpo,".txt"); fclose(fpo); fp=fopen(fnn,"rb"); if(fp==NULL) {printf("入力したファイルはありません");}
scanfで入力した画像ファイル名をitizi,txtに書き込み、fopenを利用して、入力した画像ファイル名が存在するかどうかを判断して、ファイルが存在していれば次の処理に移り、存在していなければ"入力したファイルはありません"と表示されます。
・画像のデータを読み込む部分
fread(header,1,54,fp); ←ここと fread(screen,1,640*480*3,fp); ←ここで画像を読み取って FILE*sss; FILE*ss; sss=fopen("111.txt","wb");←ここから fwrite(header,1,54,sss); ss=fopen("222.txt","wb"); fwrite(screen,1,640*480*3,ss);←ここで画像データを111.txtと222.txtに書き込んでいる。
画像をfreadで読み込んで、fwriteで、読み取ったデータを文字としてtxtファイルに書き込んでいる。
・暗号化する部分
printf("パスワードを入力してください4桁以内のすうちのみ"); scanf("%d",&k); on=fopen("111.txt","rb"); to=fopen("222.txt","rb"); ow=fopen("b111.txt","wb"); wo=fopen("b222.txt","wb"); while((v=getc(on))!=EOF) {putc(v+k,ow);} ←ここと while((v=getc(to))!=EOF) {putc(v+k,wo);}←ここでkだけ文字をシフトさせる
scanfで入力した数値(パスワード)kの分だけ画像ファイルの書き込まれた二つのtxtファイル内の文字をシフトさせて暗号化する。
・復号化する部分
復号化部分
while((v=getc(th))!=EOF) {putc(v-k,on);} while((v=getc(f))!=EOF) {putc(v-k,to);}
暗号化部分
while((v=getc(on))!=EOF) {putc(v+k,ow);} while((v=getc(to))!=EOF) {putc(v+k,wo);}
シーザー暗号は暗号化した時にシフトした数だけ元に戻せばいいので、v+kがv-kになっている。
問題点
・約900KBまでの画像しか暗号化できない。それ以上のサイズの画像だとオーバーフローして画像が正常に暗号化できない。画像の一部が無くなる。
・ファイル名をわざわざ拡張子(.jpgや.pngなど)込みで入力しなければいけない。
・画像を1個ずつしか暗号化できない。
・画像の名前が長すぎると暗号化できない。
・画像の名前に空欄が含まれていると暗号化できない 例:「abc 1.jpg」
・パスワードは4桁以内の半角数字のみ。パスワードが9999より大きな数字になると、正常に暗号化できない。画質の高い画像等、画像によっては9999以内でさえ暗号化できない(データが大きくなってオーバーフローする)。