Base 64 encodée

Download | Vote Up (1) | Vote Down (0)
#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


Be the first to give feedback !

Please login to comment !