c言語でファイルをbase64変換する
c言語でドラッグ&ドロップでbase64のエンコードとデコードしたかったので作りました。
コードは無駄に長くなっています。
前に作ったことはあるのですが、あのときは全てメモリ上で扱っていたためサイズが大きいと扱えなかったため、今回はファイルに3バイトずつ書き込むことで改善しています。
あとシフト演算子の優先順位の考えを理解していなく、結構詰まりました。
もうシフト演算子を使うときは括弧でくくりまくります。
ファイル名やディレクトリの操作を自分で行っているため全角文字が含まれている場合に対応していません。
githubにあげればいいのですが、githubよりこっちの方が見返しやすいので。
#include <stdio.h> #include <stdlib.h> #include<string.h> //0:directory, 1:file void getFileName(char *filepath,char *getname,int flag) { //get size and '\' count int size=0,slash=0; for(int i=0;;i++){ if(filepath[i]==0)break; size++; if(filepath[i]=='\\')slash++; } //1:file if(flag==1){ //get file name (reverse) char temp[200]={}; int j=0; for(int i=size-1;i>0;i--){ if(filepath[i]=='\\')break; temp[j]=filepath[i]; j++; } //put file name for(int i=0;;i++){ if(j<0 || temp[j-1]=='\"'){ getname[i]=0; break; } getname[i]=temp[j-1]; j--; } }else{ //0:directory int slash2=0; for(int i=0;;i++){ if(filepath[i]=='\\')slash2++; if(slash2==slash){ getname[i]=0; break; } getname[i]=filepath[i]; } } } int b64table(int b64) { int ascii=-1; //0~9 48~57 -> 52~61 if (b64 >= 48 && b64 <= 57)ascii = b64 + 4; //A~Z 65~90 -> 0~25 if (b64 >= 65 && b64 <= 90)ascii = b64 - 65; //a~z 97~122 -> 26~51 if (b64 >= 97 && b64 <= 122)ascii = b64 - 71; //'+' 43 -> 62 if (b64 == 43)ascii = b64 + 19; //'/' 47 -> 63 if (b64 == 47)ascii = b64 + 16; //'=' 61 -> 0 if (b64 == 61)ascii = 0; //error if (b64 == -1)printf("ascii=%d\n",b64); return ascii; } //4 characters(4*6=24 bits) void b64decode(char *fname) { FILE *fp,*fp2; fp=fopen(fname,"rb"); char fname2[200],fname3[200]; getFileName(fname,fname2,0); getFileName(fname,fname3,1); strcat(fname2,"\\b64de_"); strcat(fname2,fname3); fp2=fopen(fname2,"wb"); int de1,de2,de3; while(1){ int a=fgetc(fp); if(a==-1)break; int b=fgetc(fp); int c=fgetc(fp); int d=fgetc(fp); de1=(b64table(a)<<2)+(b64table(b)>>4); de2=((b64table(b)&0b1111)<<4)+(b64table(c)>>2); de3=((b64table(c)&0b11)<<6)+b64table(d); fputc(de1,fp2); fputc(de2,fp2); fputc(de3,fp2); } fclose(fp); fclose(fp2); } //3 characters(3*8=24 bits) void b64encode(char *fname) { char base64[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; FILE *fp,*fp2; fp=fopen(fname,"rb"); char fname2[200],fname3[200]; getFileName(fname,fname2,0); getFileName(fname,fname3,1); strcat(fname2,"\\b64en_"); strcat(fname2,fname3); fp2=fopen(fname2,"wb"); int en1,en2,en3,en4; while(1){ int a=fgetc(fp); if(a==-1)break; int b=fgetc(fp); if(b==-1){ en1=base64[a>>2]; en2=base64[(a&0b11)<<4]; fputc(en1,fp2); fputc(en2,fp2); fputc('=',fp2); fputc('=',fp2); break; } int c=fgetc(fp); if(c==-1){ en1=base64[a>>2]; en2=base64[((a&0b11)<<4)+(b>>4)]; en3=base64[(b&0b1111)<<2]; fputc(en1,fp2); fputc(en2,fp2); fputc(en3,fp2); fputc('=',fp2); break; } en1=base64[a>>2]; en2=base64[((a&0b11)<<4)+(b>>4)]; en3=base64[((b&0b1111)<<2)+(c>>6)]; en4=base64[c&0b111111]; fputc(en1,fp2); fputc(en2,fp2); fputc(en3,fp2); fputc(en4,fp2); } fclose(fp); fclose(fp2); } int main(int argc, char *argv[]) { //D&D default:decode if(argc==2){ b64decode(argv[1]); //b64encode(argv[1]); return 0; } puts("D&D default:decode"); puts("decode:0"); puts("encode:1"); puts("format: filepath num"); puts("example: C:\\test.txt 1"); char fname[200]; int f=0; scanf("%s %d",fname,&f); if(f==1)b64encode(fname); else b64decode(fname); return 0; }
コメント
0 件のコメント :
コメントを投稿