/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        C H I F F R A G E   S T E G A N O G R A P H I Q U E  :                                                                     */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        Author of '$xcg/chiffrage.21$K' :                                                                                          */
/*                                                                                                                                   */
/*                    Jean-Francois COLONNA (LACTAMME, 1996??????????).                                                              */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        I N T E R F A C E   ' listG '  :                                                                                           */
/*                                                                                                                                   */
/*                                                                                                                                   */
/*        :Debut_listG:                                                                                                              */
/*        :Fin_listG:                                                                                                                */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        D I R E C T I V E S   S P E C I F I Q U E S   D E   C O M P I L A T I O N  :                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        F I C H I E R S   D ' I N C L U D E S  :                                                                                   */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#include  INCLUDES_MINI

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        P A R A M E T R E S  :                                                                                                     */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   CHIFFRER                                                                                                                      \
                    VRAI                                                                                                                \
                                        /* Faut-il chiffrer ('VRAI') ou dechiffrer ('FAUX').                                         */

#define   DEFINIR_LE_TEXTE_AVEC_UNE_CHAINE_DE_CARACTERES                                                                                \
                    VRAI                                                                                                                \
                                        /* Faut-il definir le texte a chiffrer avec une chaine de caracteres ('VRAI') ou bien        */ \
                                        /* avec un fichier ('FAUX'). On notera le 20051110114231 l'interet de passer par un          */ \
                                        /* fichier (surtout s'il est dans '$DStemporaires' -en ce qui concerne des MACHINEs telle    */ \
                                        /* '$CMAP28' dont le File System supporte des "snapshots" ce qui rend difficile de se        */ \
                                        /* debarasser rapidement des fichiers detruits- et detruit apres usage) : en effet, le texte */ \
                                        /* a chiffrer n'apparait alors pas dans l'history de la MACHINE, ce qui est necessaire pour  */ \
                                        /* des raisons evidentes de securite...                                                      */

#define   PREMIER_CARACTERE_A_MODIFIER                                                                                                  \
                    QUARANTE                                                                                                            \
                                        /* Index du premier caractere du fichier Argument a modifier (eviter les puissances de 2).   */
#define   DERNIER_CARACTERE_A_MODIFIER                                                                                                  \
                    INFINI                                                                                                              \
                                        /* Index du dernier caractere du fichier Argument a modifier (eviter les puissances de 2).   */
#define   PAS_DES_INDEX_DES_CARACTERES_A_MODIFIER                                                                                       \
                    CINQUANTE                                                                                                           \
                                        /* Pas de passage d'un caractere a modifier au suivant (eviter les puissances de 2),         */ \
                                        /* sachant qu'un seul bit est modifie par caractere...                                       */

#define   POIDS_DU_BIT_A_UTILISER                                                                                                       \
                    BIT0                                                                                                                \
                                        /* Donne le poids du bit a utiliser (a priori, celui de poids le plus faible...).            */

#define   CARACTERE_DE_REMPLISSAGE                                                                                                      \
                    K_NULL                                                                                                              \
                                        /* Afin de mettre a la suite du texte a cacher lorsqu'il est trop court...                   */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        M A C R O S   U T I L E S  :                                                                                               */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
#define   TAILLE_EFFECTIVE_DU_TEXTE_A_CHIFFRER                                                                                          \
                    COND(IL_FAUT(definir_le_texte_avec_une_chaine_de_caracteres)                                                        \
                        ,chain_Xtaille(texte_a_chiffrer)                                                                                \
                        ,nombre_de_caracteres_du_fichier_definissant_le_texte_a_chiffrer                                                \
                         )                                                                                                              \
                                        /* Taille effective du texte a chiffrer en fonction de sa provenance.                        */

/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        C H I F F R A G E   S T E G A N O G R A P H I Q U E  :                                                                     */
/*                                                                                                                                   */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
     Bblock
     DEFV(Logical,INIT(chiffrer,CHIFFRER));
                                        /* Faut-il chiffrer ('VRAI') ou dechiffrer ('FAUX').                                         */

     DEFV(Logical,INIT(definir_le_texte_avec_une_chaine_de_caracteres,DEFINIR_LE_TEXTE_AVEC_UNE_CHAINE_DE_CARACTERES));
                                        /* Faut-il definir le texte a chiffrer avec une chaine de caracteres ('VRAI') ou bien        */
                                        /* avec un fichier ('FAUX'). On notera le 20051110114231 l'interet de passer par un          */
                                        /* fichier (surtout s'il est dans '$DStemporaires' -en ce qui concerne des MACHINEs telle    */
                                        /* '$CMAP28' dont le File System supporte des "snapshots" ce qui rend difficile de se        */
                                        /* debarasser rapidement des fichiers detruits- et detruit apres usage) : en effet, le texte */
                                        /* a chiffrer n'apparait alors pas dans l'history de la MACHINE, ce qui est necessaire pour  */
                                        /* des raisons evidentes de securite...                                                      */
     DEFV(CHAR,INIC(POINTERc(nom_fichier),NOM_PIPE));
     DEFV(Int,INIT(nombre_de_caracteres_du_fichier_definissant_le_texte_a_chiffrer,UNDEF));
                                        /* Definition du fichier contenant le texte a chiffre si besoin est, c'est-a-dire si         */
                                        /* 'IL_NE_FAUT_PAS(definir_le_texte_avec_une_chaine_de_caracteres)'.                         */
     DEFV(Logical,INIT(editer_les_messages_d_erreur,EDITER_LES_MESSAGES_D_ERREUR_DES_FICHIERS));
                                        /* Indicateur a utiliser pour editer les messages d'erreur des fichiers.                     */

     DEFV(Int,INIT(premier_caractere_a_modifier,PREMIER_CARACTERE_A_MODIFIER));
                                        /* Index du premier caractere du fichier Argument a modifier (eviter les puissances de 2).   */
     DEFV(Int,INIT(dernier_caractere_a_modifier,DERNIER_CARACTERE_A_MODIFIER));
                                        /* Index du dernier caractere du fichier Argument a modifier (eviter les puissances de 2).   */
     DEFV(Int,INIT(pas_des_index_des_caracteres_a_modifier,PAS_DES_INDEX_DES_CARACTERES_A_MODIFIER));
                                        /* Pas de passage d'un caractere a modifier au suivant (eviter les puissances de 2),         */
                                        /* sachant qu'un seul bit est modifie par caractere...                                       */

     DEFV(Int,INIT(poids_du_bit_a_utiliser,POIDS_DU_BIT_A_UTILISER));
                                        /* Donne le poids du bit a utiliser (a priori, celui de poids le plus faible...).            */

     DEFV(CHAR,INIC(POINTERc(texte_a_chiffrer),C_VIDE));
                                        /* Texte a chiffrer grace a une methode steganographique.                                    */

     DEFV(Int,INIT(caractere_courant_de_fichierA,UNDEF));
     DEFV(Int,INIT(index_du_caractere_courant_de_fichierA,PREMIER_CARACTERE));
                                        /* Donnees du fichier Argument.                                                              */
                                        /* ATTENTION, on utilise 'Int' et non pas 'Char' pour 'caractere_courant_de_fichierA' a      */
                                        /* cause de l'usage qui sera fait ci-apres de 'GetcharQ(...)', et ce afin que le test de     */
                                        /* fin de fichier fonctionne correctement...                                                 */
     DEFV(CHAR,INIT(caractere_courant_de_fichierR,K_NULL));
     DEFV(Int,INIT(index_du_caractere_courant_du_texte_a_chiffrer,PREMIER_CARACTERE));
     DEFV(Int,INIT(amplitude_du_decalage,ZERO));
                                        /* Donnees du fichier Resultat.                                                              */
     DEFV(CHAR,INIT(caractere_de_remplissage,CARACTERE_DE_REMPLISSAGE));
                                        /* Afin de mettre a la suite du texte a cacher lorsqu'il est trop court...                   */
     /*..............................................................................................................................*/
     GET_ARGUMENTS_(nombre_d_arguments
                   ,BLOC(GET_ARGUMENT_L("chiffrer=",chiffrer);
                         GET_ARGUMENT_N("dechiffrer=",chiffrer);
                                        /* Parametre introduit le 20051110112911...                                                  */

                         GET_ARGUMENT_L("definition_par_chaine=""dc=""chaine=",definir_le_texte_avec_une_chaine_de_caracteres);
                         GET_ARGUMENT_C("texte=""message=""chaine_a_chiffrer=",texte_a_chiffrer);
                                        /* Parametre introduit le 20051110113057...                                                  */
                         GET_ARGUMENT_N("df=""definition_par_fichier=",definir_le_texte_avec_une_chaine_de_caracteres);
                         GET_ARGUMENT_C("fichier=""fichier_a_chiffrer=""f=""F=",nom_fichier);

                         GET_ARGUMENT_L("erreurs=",editer_les_messages_d_erreur);

                         GET_ARGUMENT_I("premier=",premier_caractere_a_modifier);
                         GET_ARGUMENT_I("dernier=",dernier_caractere_a_modifier);
                         GET_ARGUMENT_I("pas=",pas_des_index_des_caracteres_a_modifier);
                         GET_ARGUMENT_I("poids=",poids_du_bit_a_utiliser);
                         GET_ARGUMENT_K("remplissage=",caractere_de_remplissage);
                         )
                    );

     Test(IFEXff(poids_du_bit_a_utiliser,BIT0,TRMU(NBITOC)))
          Bblock
          PRINT_ERREUR("le poids du bit a utiliser est inexistant");
          CAL1(Prer1("(la valeur par defaut (%d) est forcee)\n",POIDS_DU_BIT_A_UTILISER));

          EGAL(poids_du_bit_a_utiliser,POIDS_DU_BIT_A_UTILISER);
          Eblock
     ATes
          Bblock
          Eblock
     ETes

     Test(IL_FAUT(chiffrer))
          Bblock
          Test(IL_FAUT(definir_le_texte_avec_une_chaine_de_caracteres))
               Bblock
               Eblock
          ATes
               Bblock
               CALS(Fsize_fichier(nom_fichier
                                 ,ADRESSE(nombre_de_caracteres_du_fichier_definissant_le_texte_a_chiffrer)
                                 ,editer_les_messages_d_erreur
                                  )
                    );
                                        /* Nombre de caracteres du fichier definissant le texte a chiffrer...                        */

               EGAL(texte_a_chiffrer,kMalo(nombre_de_caracteres_du_fichier_definissant_le_texte_a_chiffrer));
                                        /* Allocation de la memoire temporaire necessaire.                                           */

               CALS(Fload_fichier_non_formatte(nom_fichier
                                              ,texte_a_chiffrer
                                              ,nombre_de_caracteres_du_fichier_definissant_le_texte_a_chiffrer
                                              ,size_char
                                              ,editer_les_messages_d_erreur
                                              ,editer_les_messages_d_erreur
                                               )
                    );
                                        /* Chargement du fichier definissant le texte a chiffrer...                                  */
               Eblock
          ETes

          EGAL(index_du_caractere_courant_du_texte_a_chiffrer,PREMIER_CARACTERE);
                                        /* Initialisation (a priori inutile) de l'index du texte a chiffrer...                       */

          Repe(TAILLE_EFFECTIVE_DU_TEXTE_A_CHIFFRER)
               Bblock
               Test(IFEQ(ITb0(texte_a_chiffrer,INDX(index_du_caractere_courant_du_texte_a_chiffrer,PREMIER_CARACTERE))
                        ,caractere_de_remplissage
                         )
                    )
                    Bblock
                    PRINT_ERREUR("le texte a chiffrer contient le caractere de remplissage");
                    CAL1(Prer1("(son code est %02X)\n",caractere_de_remplissage));
                    Eblock
               ATes
                    Bblock
                    Eblock
               ETes

               INCR(index_du_caractere_courant_du_texte_a_chiffrer,I);
                                        /* Progression de l'index du texte a chiffrer...                                             */
               Eblock
          ERep

          EGAL(index_du_caractere_courant_du_texte_a_chiffrer,PREMIER_CARACTERE);
                                        /* Re-initialisation de l'index du texte a chiffrer...                                       */

          Tant(GetcharQ(caractere_courant_de_fichierA))
               Bblock
                                        /* Le caractere courant de l'entree courante est recupere ; et on boucle                     */
                                        /* sur cette recuperation tant que l'on n'est pas au bout du fichier.                        */
               Test(IFET(IFINff(index_du_caractere_courant_de_fichierA,premier_caractere_a_modifier,dernier_caractere_a_modifier)
                        ,DIVISIBLE(SOUS(index_du_caractere_courant_de_fichierA,premier_caractere_a_modifier)
                                  ,pas_des_index_des_caracteres_a_modifier
                                   )
                         )
                    )
                    Bblock
                    EGAL(caractere_courant_de_fichierR
                        ,OUIN(ETLO(caractere_courant_de_fichierA
                                  ,OUEX(MOCD
                                       ,SLLS(BIT,poids_du_bit_a_utiliser)
                                        )
                                   )
                             ,SLLS(ETLO(SLRS(COND(IFLE(index_du_caractere_courant_du_texte_a_chiffrer
                                                      ,LSTX(PREMIER_CARACTERE,TAILLE_EFFECTIVE_DU_TEXTE_A_CHIFFRER)
                                                       )
                                                 ,ITb0(texte_a_chiffrer
                                                      ,INDX(index_du_caractere_courant_du_texte_a_chiffrer,PREMIER_CARACTERE)
                                                       )
                                                 ,caractere_de_remplissage
                                                  )
                                            ,amplitude_du_decalage
                                             )
                                       ,BIT
                                        )
                                  ,poids_du_bit_a_utiliser
                                   )
                              )
                         );
                                        /* Cas ou le caractere courant du fichier Argument doit etre chiffre...                      */

                    INCR(amplitude_du_decalage,LBIT);
                                        /* Passage au bit suivant du texte a chiffrer...                                             */
                    Test(IFGE(amplitude_du_decalage,NBITOC))
                         Bblock
                         EGAL(amplitude_du_decalage,ZERO);
                         INCR(index_du_caractere_courant_du_texte_a_chiffrer,I);
                                        /* Lorsque l'on "sort" du caractere courant, on passe au suivant...                          */
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes
                    Eblock
               ATes
                    Bblock
                    EGAL(caractere_courant_de_fichierR
                        ,caractere_courant_de_fichierA
                         );
                                        /* Cas ou le caractere courant du fichier Argument n'est pas chiffre...                      */
                    Eblock
               ETes

               CALS(Putchar(caractere_courant_de_fichierR));
                                        /* Le caractere courant est emis...                                                          */
               INCR(index_du_caractere_courant_de_fichierA,I);
                                        /* Index du caractere suivant...                                                             */
               Eblock
          ETan

          Test(IFLE(index_du_caractere_courant_du_texte_a_chiffrer,LSTX(PREMIER_CARACTERE,TAILLE_EFFECTIVE_DU_TEXTE_A_CHIFFRER)))
               Bblock
               PRINT_ERREUR("tous les bits n'ont pas ete codes");
               Eblock
          ATes
               Bblock
                                        /* Cas ou il n'y a rien a recuperer : il n'y a donc rien a faire...                          */
               Eblock
          ETes
          Eblock
     ATes
          Bblock
          Tant(GetcharQ(caractere_courant_de_fichierA))
               Bblock
                                        /* Le caractere courant de l'entree courante est recupere ; et on boucle                     */
                                        /* sur cette recuperation tant que l'on n'est pas au bout du fichier.                        */
               Test(IFET(IFINff(index_du_caractere_courant_de_fichierA,premier_caractere_a_modifier,dernier_caractere_a_modifier)
                        ,DIVISIBLE(SOUS(index_du_caractere_courant_de_fichierA,premier_caractere_a_modifier)
                                  ,pas_des_index_des_caracteres_a_modifier
                                   )
                         )
                    )
                    Bblock
                    EGAL(caractere_courant_de_fichierR
                        ,OUIN(SLLS(SLRS(ETLO(caractere_courant_de_fichierA
                                            ,SLLS(BIT,poids_du_bit_a_utiliser)
                                             )
                                       ,poids_du_bit_a_utiliser
                                        )
                                  ,amplitude_du_decalage
                                   )
                             ,caractere_courant_de_fichierR
                              )
                         );
                                        /* Cas ou il y a un bit a recuperer dans le caractere courant...                             */

                    INCR(amplitude_du_decalage,LBIT);
                                        /* Passage au bit suivant du texte a chiffrer...                                             */
                    Test(IFGE(amplitude_du_decalage,NBITOC))
                         Bblock
                         Test(IFNE(caractere_courant_de_fichierR,caractere_de_remplissage))
                              Bblock
                              CALS(Putchar(caractere_courant_de_fichierR));
                                        /* Le caractere courant est emis a condition que ce ne soit pas un 'NULL' auquel cas, il     */
                                        /* correspond a du remplissage a la suite du texte cache...                                  */
                              Eblock
                         ATes
                              Bblock
                              Eblock
                         ETes

                         EGAL(caractere_courant_de_fichierR,K_NULL);
                                        /* Preparation du caractere suivant...                                                       */
                         EGAL(amplitude_du_decalage,ZERO);
                         INCR(index_du_caractere_courant_du_texte_a_chiffrer,I);
                                        /* Lorsque l'on "sort" du caractere courant, on passe au suivant...                          */
                         Eblock
                    ATes
                         Bblock
                         Eblock
                    ETes
                    Eblock
               ATes
                    Bblock
                                        /* Cas ou il n'y a rien a recuperer : il n'y a donc rien a faire...                          */
                    Eblock
               ETes

               INCR(index_du_caractere_courant_de_fichierA,I);
                                        /* Index du caractere suivant...                                                             */
               Eblock
          ETan

          Test(IZNE(amplitude_du_decalage))
               Bblock
                                        /* ATTENTION, ce n'est pas une erreur car, en effet, rien ne prouve que le nombre de         */
                                        /* caracteres du fichier Argument soit (a une translation pres) divisible par le pas...      */
               Eblock
          ATes
               Bblock
               Eblock
          ETes
          Eblock
     ETes

     RETU_Commande;
     Eblock
ECommande



Copyright © Jean-François COLONNA, 2019-2024.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2019-2024.