#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> //-- Constante des chaines de caractères différents plus le = du complément ---- #define ERROR_00 "00 : Parametres incorrect." #define ERROR_01 "01 : Impossible d accéder au fichier en lecture." #define ERROR_02 "02 : Erreur lors de l ecriture du fichier." #define ERROR_03 "03 : L ecriture dans le fichier a echoue." #define ERROR_FF "FF : Une erreur est apparue." #define DEFAULT_WIDTH 72 #define MINIMAL_WIDTH 4 //-- Definitiondes chaines de caractères différents plus le = du complément ---- #define bool int #define true 1 #define false 0 //-- Constante des chaines de caractères différents plus le symbole du complément ---- char ConstChar[65]="AQWmzoslVFRBGTYeidZSXED%CH928v7NJUI56+apqkKLOPM04rufjtgyhwnxbc1@3"; //char ConstChar[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" //-- Encode en base 64 --------------------------------------------------------- void EncodeBase64(int src[3], int dst[4], short len) { dst[0] = (src[0] & 0xFC) >> 2; dst[1] = ((src[0] & 0x03) << 4) | ((src[1] & 0xF0) >> 4); if(len==2) dst[2]=64; else dst[2] = ((src[1] & 0x0F) << 2) | ((src[2] & 0xC0) >> 6); if(len>=1) dst[3]=64; else dst[3] = src[2] & 0x3F; } //-- Lit le fichier et l encode dans le fichier destination -------------------- void EncodeFile(char strSrcFile[256], char strDstFile[256], int iCRLF) { bool loop=true; int rep[3]={0,0,0},index=0; int cod[4]={0,0,0,0}; // Determine le nombre de mots de 6 bits a codes restants, donc le nombre // de = a mettre en fin d encodage unsigned short len; FILE *o_s, *i_s; // Test pour une erreur de flux en lecture i_s=fopen(strSrcFile,"rb"); if(!i_s) {printf("/n/n/a+ Erreur : %s",ERROR_01); exit(-1);} // Test pour une erreur de flux en ecriture o_s=fopen(strDstFile,"wb"); if(!o_s) {printf("/n/n/a+ Erreur : %s",ERROR_02); exit(-1);} if( strcmp(strSrcFile,"-tmp.-tmp") ) printf("/nEncoding %s to %s...",strSrcFile,strDstFile); do { len=0; rep[0]=fgetc(i_s); rep[1]=fgetc(i_s); rep[2]=fgetc(i_s); if( rep[0] < 0 ) { len=0; rep[0] = 0; break; } if( rep[1] < 0 ) { len++; rep[1] = 0; loop=false; } if( rep[2] < 0 ) { len++; rep[2] = 0; loop=false; } EncodeBase64(rep,cod,len); // Une erreur d ecriture > exit. if( fputc(ConstChar[cod[0]],o_s) < 0 ) { printf("/n/n/a+ Erreur : %s",ERROR_03); exit(-1); } else { index++; } if(index==iCRLF) {fprintf(o_s,"/r/n");index = 0;} fputc(ConstChar[cod[1]],o_s); index++; if(index==iCRLF) {fprintf(o_s,"/r/n");index = 0;} fputc(ConstChar[cod[2]],o_s); index++; if(index==iCRLF) {fprintf(o_s,"/r/n");index = 0;} fputc(ConstChar[cod[3]],o_s); index++; if(index==iCRLF) {fprintf(o_s,"/r/n");index = 0;} } while( loop == true ); if( strcmp(strSrcFile,"-tmp.-tmp") ) printf("done./n"); else printf("/n"); fclose(i_s); fclose(o_s); } //-- Encode en base 2 ---------------------------------------------------------- void DecToBin(int n, int *CODE, int NbrBitsLength) { int i,nb=NbrBitsLength; for(i=nb-1;i>=0;i--) { CODE[i]=n%2; n/=2; if(n<0) break; } } //-- Fonction puissance -------------------------------------------------------- int powa(int x, int n) { int i=0,r=1; for(i=0;i<n;i++) { r*=x; } return(r); } /*-- Encode en base 10 depuis la base 2 ---------------------------------------- 2 ^ 7 = 128 * 1 = 128 8 - i + Start - 1 + 2 ^ 6 = 64 * 1 = 192 + 2 ^ 5 = 32 * 1 = 224 8 - 8 + 8 - 1 = 7 + 2 ^ 4 = 16 * 1 = 240 8 - 9 + 9 - 1 = 6 + 2 ^ 3 = 8 * 1 = 248 8 - 16 + 16 - 1 = 7 + 2 ^ 2 = 4 * 1 = 252 8 - 17 + 17 - 1 = 6 + 2 ^ 1 = 2 * 1 = 254 on revient en 7 à chaque fois... + 2 ^ 0 = 1 * 1 = 255 Donc on a bien un octet code sur 8 bits (0 -> 255 => 0 -> FF) */ int BinToDec(int *CODE, int Start, int Last) { int i,R=0; for(i=Start;i<=Last;i++) { R+=CODE[i]*(int)powa(2,8-i+Start-1); } return(R); } //-- Decode en base 64 --------------------------------------------------------- void DecodeBase64(int src[4], int dst[3]) { int i,j,k,step=-6; int tmp[6],buff[24]; for(j=0;j<4;j++) // Dans nos quatres mots de 8 bits... { // on cherche la correspondance step+=6; // avec l alphabet base 64 for(i=0;i<65;i++) // et on rempli le buffer 6 bits par 6 { if(src[j]==ConstChar[i]) { if(i==64) // Si on est sur le caractère de { // complément = alors on est sur src[j]=0; // le dernier octet } else { DecToBin(i,tmp,6); // On met en binaire l équivalent du for(k=step;k<step+6;k++) // caractère lu et trouvé dans la base { // puis on le sauvegarde par mots buff[k]=tmp[k%6]; // de 6 bits dans une variable } // temporaire pour ensuite regrouper } // les quatres mots de 6 bits en } // un seul buffer de 24 bits } } dst[0]=BinToDec(buff,0,7); // qu on pourra ici décomposer dst[1]=BinToDec(buff,8,15); // en 3 mots de 8 bits dst[2]=BinToDec(buff,16,23); // } //-- Lit le fichier et le décode dans le fichier destination ------------------- void DecodeFile(char strSrcFile[256], char strDstFile[256]) { bool loop=true; int rep[4]={0,0,0,0}; int dcd[3]={0,0,0},tmp; unsigned short len; FILE *i_s=fopen(strSrcFile,"rb"); FILE *o_s=fopen(strDstFile,"wb"); if(!i_s) {printf("/n/n/a+ Erreur : %s",ERROR_01); exit(-1);} if(!o_s) {printf("/n/n/a+ Erreur : %s",ERROR_02); exit(-1);} if( strcmp(strSrcFile,"-tmp.-tmp") ) printf("/nDecoding %s to %s...",strSrcFile,strDstFile); else printf("/n"); do { len=0; // Un caractere est mis dans une variable temporaire pour tester si on // est sur un saut de ligne, si c est le cas on lit le caractere suivant // et on sauvegarde le caractere d apres dans notre tampon REP, autrement // on sauvegarde directement dans le tampon REP tmp=fgetc(i_s); if(tmp==0xD) { fgetc(i_s); rep[0]=fgetc(i_s); } else rep[0]=tmp; tmp=fgetc(i_s); if(tmp==0xD) { fgetc(i_s); rep[1]=fgetc(i_s); } else rep[1]=tmp; tmp=fgetc(i_s); if(tmp==0xD) { fgetc(i_s); rep[2]=fgetc(i_s); } else rep[2]=tmp; tmp=fgetc(i_s); if(tmp==0xD) { fgetc(i_s); rep[3]=fgetc(i_s); } else rep[3]=tmp; if( rep[0] < 0 ) { rep[0] = 0; break; } if( rep[1] < 0 ) { rep[1] = 0; loop=false; } // Si le caractere est if( rep[2] < 0 ) { rep[2] = 0; loop=false; } // celui de fin de fichier if( rep[3] < 0 ) { rep[2] = 0; loop=false; } // EOF == -1 DecodeBase64(rep,dcd); // On decode les 4 mots // en 3 octets // Une erreur d ecriture > exit. // Puis on les ecrits en if(fputc(dcd[0],o_s)<0) {printf("/n/n/a+ Erreur : %s",ERROR_03); exit(-1);} if( rep[2] > 0 ) fputc(dcd[1],o_s); // verifiant bien qu ils if( rep[3] > 0 ) fputc(dcd[2],o_s); // ne proviennent pas de = // le saut de ligne } while( loop == true ); // Tout ceci tant que // on est pas a la fin. if( strcmp(strSrcFile,"-tmp.-tmp") ) printf("done./n"); fclose(i_s); fclose(o_s); } //-- Synopsis ------------------------------------------------------------------ void Usage(int more) { if(more) printf("/nConvertisseur Base64Encoded (par Nicolas@secureinfo.free.fr)" "/nB64 [-f|-s] [-e|-d] [input_file|chaine_de_caractere] [output_file] [[-l 80]]" "/n " "/n-f : specifie le traitement de fichier " "/n-s : specifie une chaine de caractere " "/n-e : encodage en base 64 " "/n-d : decodage en base 64 " "/n-l : (optionel) longueur de la ligne encodee /n" "/nEncodage d un fichier ............: b64 -f -e test.txt code.txt" "/nDecodage d un fichier ............: b64 -f -d code.txt decode.txt" "/nLigne de 50 caracteres ...........: b64 -f -e test.txt code.txt -l 50" "/nPar defaut le programme encodera un fichier sur une ligne de 72 caracteres" "/nle minimum de caractere sur une ligne est de 4 caracteres (24bits, 3octets)" "/nEncodage d une chaine de caractere: b64 -s -e ABCD" "/nDecodage d une chaine de caractere: b64 -s -d QUJDRA==/n"); else printf("/nConvertisseur Base64Encoded" "/nB64 [-f|-s] [-e|-d] [input_file|chaine_de_caractere] [output_file] [[-l 80]]/n" "/nPar defaut le programme encodera un fichier sur une ligne de 72 caracteres" "/nle minimum de caractere sur une ligne est de 4 caracteres (24bits, 3octets)/n"); } //-- Ecriture du fichier temporaire -------------------------------------------- void WriteInFile(char *Buffer, char *FileName) { FILE *flux; flux=fopen(FileName,"wb"); if(!flux) {printf("/n/n/a+ Erreur : %s",ERROR_02); exit(-1);} fprintf(flux,"%s",Buffer); fclose(flux); } //-- Affichage du fichier temporaire ------------------------------------------- void ViewFile(char *FileName) { int rep; FILE *flux; flux=fopen(FileName,"rb"); if(!flux) {printf("/n/n/a+ Erreur : %s",ERROR_01); exit(-1);} while( (rep=fgetc(flux)) != EOF ) printf("%c",rep); fclose(flux); unlink("-tmp.-tmp"); unlink("_tmp._tmp"); } //-- Determine l operation a effectuer (encodage, decodage) -------------------- #define is_ok strlen(argv[3])>=1 / && strlen(argv[3])<=256 / && strlen(argv[4])>=1 / && strlen(argv[4])<=256 #define is_ok_s strlen(argv[3])>=1 / && strlen(argv[3])<=1024/ void SelectOperation(int argc, char *argv[]) { // Traitement d une chaine de caractere if( argc == 4 ) { if( ! strcmp(argv[1],"-s") ) { if( ! strcmp(argv[2],"-e") ) // -> Encode { // la chaine de caractere if( is_ok_s ) { // Ecriture dans un fichier temporaire WriteInFile(argv[3],"-tmp.-tmp"); EncodeFile( "-tmp.-tmp" , "_tmp._tmp" , DEFAULT_WIDTH ); ViewFile("_tmp._tmp"); printf("/n/n"); } } if( ! strcmp(argv[2],"-d") ) // -> Decode { // la chaine de caractere if( is_ok_s ) { WriteInFile(argv[3],"-tmp.-tmp"); DecodeFile( "-tmp.-tmp" , "_tmp._tmp" ); ViewFile("_tmp._tmp"); printf("/n/n"); } } } return; } // Il s agit d encoder ou de decoder un fichier if( argc == 5 ) { if(!strcmp(argv[1],"-f")) // Fichier { if(is_ok) { if( ! strcmp(argv[2],"-e") ) // -> Encode le fichier EncodeFile( argv[3] , argv[4] , DEFAULT_WIDTH ); if( ! strcmp(argv[2],"-d") ) // -> Decode le fichier DecodeFile( argv[3] , argv[4] ); } } return; } // Il s agit d encoder avec une largeur specifiee if( argc == 7 ) { if( ! strcmp(argv[1],"-f") ) { if( is_ok ) { if( ! strcmp(argv[2],"-e") ) if( ! strcmp(argv[5],"-l") ) if( atoi(argv[6]) > 4) EncodeFile( argv[3] , argv[4] , atoi(argv[6])); else {Usage(0);return;} } } return; } // Affiche l aide en complet selon le cas if( argc == 2 ) if( ! strcmp(argv[1],"-h") ) {Usage(1);return;} Usage(0); } //-- Programme principal ------------------------------------------------------- int main(int argc, char *argv[]) { // Selectionne l operation a effectue selon les arguments SelectOperation(argc, argv); }
saelyx