C / C++ Encodage

Résolu
Bilow Messages postés 1193 Statut Membre -  
Bilow Messages postés 1193 Statut Membre -
Bonjour !

J'aimerais pouvoir encoder et décoder des fichiers en C ou en C++ (les rendre inaccessible ou illisible). J'ai déjà essayé un exe qui modifie chaque caractère (char) par sa valeur en int, mais pour les chansons et images, cela ne fonctionnait pas, probablement à cause du binaire / ascii.

Quelqu'un a-t-il une solution ?
Merci !

4 réponses

fiddy Messages postés 11653 Statut Contributeur 1 847
 
Bonjour,
Si votre but est de rendre les fichiers illisibles, ce n'est pas de l'encodage qu'il faut mais du cryptage. Pour cela, il existe AES, etc.
Effectivement, si tu lis ton fichier en binaire, il faut être vigilant sur plusieurs points.
2
Hxyp Messages postés 401 Date d'inscription   Statut Membre Dernière intervention   54
 
Bonjour,
Un char est codé sur 8bits soit 1octet normalement ça ne devrait pas être un problème de manipuler un fichier binaire. Pouvez-vous nous donner un peu de code pour détailler s'il vous plait ?
1
fiddy Messages postés 11653 Statut Contributeur 1 847
 
Un char est codé sur un byte d'au moins 8 bits, pas forcément 8 bits, même si c'est souvent le cas.
0
Hxyp Messages postés 401 Date d'inscription   Statut Membre Dernière intervention   54
 
un fichier contient que des blocs de 8bits c'est de ça que je voulais parler, en lecture d'un fichier binaire le minimum qu'on peut charger est 8bits soit un char ou uint8_t. A moins qu'on puisse charger directement a partir d'un fichier un bit sans avoir à charger au minimum 8bits...
0
fiddy Messages postés 11653 Statut Contributeur 1 847
 
Le fichier ne contient pas forcément des blocs de 8 bits, cela dépend du codage.
De même que le char ne fait pas forcément 8 bits.
C'est pour ça que je suis intervenu.
0
Bilow Messages postés 1193 Statut Membre 117
 
Bonjour,

Mon but est d'ouvrir un exe, qui transforme mon fichier en un autre qui est illisible, et ensuite ouvrir un autre exe qui me rend mon fichier comme avant.

La simple présence de l'exe pourra encoder et décoder...
"il faut être vigilant sur plusieurs points" Lequels ?
Je cherche mes codes et je les envois ici dans quelques instants ;)
0
Bilow Messages postés 1193 Statut Membre 117
 
Voila, voici les codes :)
Pour un fichier texte, ca marche parfaitement, mais pour une chanson ca s'arrête à 2 Ko...
Encodeur
#include <cstdlib> 
#include <iostream> 

using namespace std; 

int main(int argc, char *argv[]) 
{ 
    // Encodeur 
    FILE* fichier=NULL; 
    FILE* sortie=NULL; 
    char filesrc [30]; 
    char sortiesrc [] = "encode.txt"; 
    char a; 
    int i; 
    cout << "Nom du fichier :" << endl; 
    cin >> filesrc; 
    fichier=fopen(filesrc, "r"); 
    if(fichier==NULL){ 
    cout << "\nCe fichier n'existe pas." << endl; 
    system("pause"); 
    return 0; 
} 
    remove(sortiesrc); // Supprime la destination 
    sortie=fopen(sortiesrc, "a"); 
    a=fgetc(fichier); 
    while(a!=EOF){ 
    fprintf(sortie, "%d ", a+0); // Ecrit la valeur du char en int (ex : \n => 10) 
    a=fgetc(fichier); 
} 
    fclose(fichier); 
    fclose(sortie); 
    system("pause"); 
    return 0; 
}


Décodeur
#include <cstdlib> 
#include <iostream> 

using namespace std; 

int main(int argc, char *argv[]) 
{ 
    FILE* fichier=NULL; 
    FILE* sortie=NULL; 
    char filesrc [30]; 
    char sortiesrc [] = "decode.txt"; 
    char a; 
    int i; 
    cout << "Entrez nom du fichier :" << endl; 
    cin >> filesrc; 
    remove(sortiesrc); 
    fichier=fopen(filesrc, "r"); 
    if(fichier==NULL){ 
    cout << "\nCe fichier n'existe pas." << endl; 
    system("pause"); 
    return 0; 
} 
    sortie=fopen(sortiesrc, "a"); 
    a='a'; // Il faut que la variable 'a' aie une valeur non nulle 
    fscanf(fichier, "%d", &i); 
    while(a!=EOF){ 
    a=i; // Conversion du int récupéré en char 
    fprintf(sortie, "%c", a); 
    fscanf(fichier, "%d", &i); 
    a=fgetc(fichier); 
} 
    fclose(fichier); 
    fclose(sortie); 
    system("pause"); 
    return 0; 
}


Merci pour votre aide.
Ps : Je viens de remarquer deux choses :
- La fonction system(),je devrais la remplacer par getch()
- Le système de fichier est celui du C (fopen). Je compilerai en C alors.
0
fiddy Messages postés 11653 Statut Contributeur 1 847
 
Si tu compiles en C, ça ne marchera pas puisque tu utilises des opérateurs non connus en C (cout, ...).
C'est mieux de ne pas mélanger les deux langages.
0
Hxyp Messages postés 401 Date d'inscription   Statut Membre Dernière intervention   54
 
Utilisez "rb" au lieu de "r" tout court pour lire du binaire et "wr" pour écrire en binaire sinon va y avoir un problème avec les sauts de lignes. En reprenant votre code :
void encode()
{
    // Encodeur
    FILE* fichier=NULL;
    FILE* sortie=NULL;
    char filesrc [30];
    char sortiesrc [] = "encode.txt";
    char buffer[4096];//buffer pour fread
    int i,fr;//i pour se deplacer dans buffer, fr retour de fread
    cout << "Nom du fichier :" << endl;
    cin >> filesrc;
    fichier=fopen(filesrc, "rb");
    if(fichier==NULL)
    {
        cout << "\nCe fichier n'existe pas." << endl;
        system("pause");
        exit(1);
    }
    remove(sortiesrc); // Supprime la destination
    sortie=fopen(sortiesrc, "a");
    
    while((fr=fread(buffer,1,4096,fichier))){
        for(i=0;i<fr;i++){
            fprintf(sortie, "%d ", buffer[i]);
        }
    }
    
    fclose(fichier);
    fclose(sortie);
    system("pause");
}
void decode()
{
    FILE* fichier=NULL;
    FILE* sortie=NULL;
    char filesrc [30];
    char sortiesrc [] = "decode.txt";
    unsigned int i;
    cout << "Entrez nom du fichier :" << endl;
    cin >> filesrc;
    remove(sortiesrc);
    fichier=fopen(filesrc, "r");
    if(fichier==NULL){
    cout << "\nCe fichier n'existe pas." << endl;
    system("pause");
    exit(1);
    }
    sortie=fopen(sortiesrc, "wb");
    while(fscanf(fichier, "%d", &i)!=EOF){
        fputc(i,sortie);
    }
    fclose(fichier);
    fclose(sortie);
    system("pause");
}

Ça reste très long comme façon de lire et écrire le mieux serait de lire et écrire et se déplacer par bloc dans un fichier
0
fiddy Messages postés 11653 Statut Contributeur 1 847
 
Utilisez "rb" au lieu de "r" tout court pour lire du binaire et "wr" pour écrire en binaire sinon va y avoir un problème avec les sauts de lignes.
Non, le b n'a aucun effet. Il est ignoré. Il est juste autorisé pour assurer une compatibilité avec l'ANSI.
Cdlt,
0
Hxyp Messages postés 401 Date d'inscription   Statut Membre Dernière intervention   54
 
J'ai fait une erreur de frappe ce n'est pas wr mais "wb" même pas fait attention merci fiddy.
Sinon oui il a un effet test le code que j'ai donné sans le b
0
Bilow Messages postés 1193 Statut Membre 117
 
Bonjour !

Je suis sous Windows et sous Linux, les codes devront être compatible pour les deux... D'ailleurs, system("pause"), je le remplace par quoi ? getch() de conio.h qui elle-même n'est pas une librairie portable ? Je compile rarement sous Linux je n'ai donc pas l'habitude.

"Je compilerai en C" Bien sûr je transforme les codes (cout, namespace, ..) ! :)

Je viens de tester vos codes, je suis bluffé... Magnifique ! Ca marche !!! =D
Et même avec de gros fichiers :P

Pourriez-vous m'expliquer comment fonctionne fread() et pourquoi le nombre 4096 (2^12) ?

Ah oui, dernière chose : quelle est la plage dans laquelle peuvent aller les char ? 10 équivaut à \n, 50 à un autre caractère mais quel est le maximum ? Et le minimum dans les négatifs ?

Merci beaucoup !!
0
Bilow Messages postés 1193 Statut Membre 117
 
Ps : Code
#include <stdio.h>
#include <stdlib.h>

void encode(void);
void decode(void);

int main(int argc, char *argv[])
{
    int choix;
    printf("Encoder : 1\nDecoder : 2\n");
    scanf("%d", &choix);
    // Ca me rappelle quand j'apprennais à programmer
    // c'était la même chose, scanf, printf, switch, ... =D
    switch(choix){
    case 1 : encode();
    break;
    case 2 : decode();
    break;
    default : break;
    }
    system("pause");
    return 0;
}

void encode()
{
    // Encodeur
    FILE* fichier=NULL;
    FILE* sortie=NULL;
    char filesrc [30];
    char sortiesrc [] = "encode.txt";
    char buffer[4096];//buffer pour fread
    int i,fr;//i pour se deplacer dans buffer, fr retour de fread
    printf("Entrez le nom du fichier :\n");
    scanf("%s", filesrc);
    fichier=fopen(filesrc, "rb");
    if(fichier==NULL)
    {
        printf("\nCe fichier n'existe pas.");
        system("pause");
        exit(1);
    }
    remove(sortiesrc); // Supprime la destination
    sortie=fopen(sortiesrc, "a");
    
    while(fr=fread(buffer,1,4096,fichier)){
        for(i=0;i<fr;i++){
            fprintf(sortie, "%d ", buffer[i]);
        }
    }
    
    fclose(fichier);
    fclose(sortie);
}
void decode()
{
    FILE* fichier = NULL;
    FILE* sortie = NULL;
    char filesrc [30];
    char sortiesrc [] = "decode.txt";
    unsigned int i;
    printf("Entrez le nom du fichier a decoder :\n");
    scanf("%s", filesrc);
    remove(sortiesrc);
    fichier=fopen(filesrc, "r");
    if(fichier==NULL){
        printf("\nCe fichier n'existe pas.\n");
        system("pause");
        exit(1);
    }
    sortie=fopen(sortiesrc, "wb");
    while(fscanf(fichier, "%d", &i)!=EOF){
        fputc(i,sortie);
    }
    fclose(fichier);
    fclose(sortie);
}
0
Hxyp Messages postés 401 Date d'inscription   Statut Membre Dernière intervention   54
 
Bonjour,
Oui vous pouvez utiliser getch() en remplacement de system("pause"), sous windows l'include sera conio.h, et sous linux ncurses.h avec l'option de lien -lncurses. Pouvez utiliser le préprocesseur pour faciliter le changement d'include :
#define linux //changer linux en autre chose pour windows

#include <stdio.h>
#include <stdlib.h>
#ifdef linux
#include <ncurses.h>
#else
#include <conio.h>
#endif


size_t fread ( void * ptr, size_t size, size_t count, FILE * stream ); http://www.cplusplus.com/reference/cstdio/fread/
le premier paramètre (ptr) est le lieu où l'on va stocker l'information c'est un void* on peut y mettre le type qu'on veut pour récupérer le type d'information qu'on veut
le second paramètre (size) est la taille du bloc en octet que l'on veut lire, par exemple si on veut lire un int qu'on sait qu'il fait 32bits (4oct) dans le fichier, le second paramètre sera 4 et en premier paramètre on renverra vers un int. On peut utiliser sizeof(int) en sachant que la taille d'un int sera le même que celui dans le fichier enfin ça peut poser un problème je pense entre système, outils, et machine 32 ou 64bits dépendant de comment ils le gèrent ..
le troisième paramètre (count) est le nombre de blocs qu'on va charger en fonction du second paramètre (size), par exemple fread(buf,4,4,fichier); va retourner 4blocs de 4octets dans buf

fwrite fait la même chose que fread mais pour l'ecriture :
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
http://www.cplusplus.com/reference/cstdio/fwrite/

Un exemple pour que vous comprenez mieux fread :
#include <stdio.h>

int main(void)
  {
    int entier[4]={1234,3495,450435,23400};
    int recupentier[4]={0,0,0,0};/* a zero pour le test avec printf */
    int i;
    FILE *fichier;

    fichier=fopen("test.txt","wb"); /* pour ecrire les int */
    fwrite(entier,4,4,fichier); /* je precise 4 a l'ecriture au lieu de sizeof  c'est vous qui decidez */
    fclose(fichier);

    for(i=0;i<4;i++) printf("recupentier[%d] = %d\n",i,recupentier[i]);
    printf("\n");
    fichier=fopen("test.txt","rb");
    fread(recupentier,4,4,fichier); /* je precise 4 à lecture pareil qu'a l'ecriture */
    fclose(fichier);
    for(i=0;i<4;i++) printf("recupentier[%d] = %d\n",i,recupentier[i]);

    return 0;
  }


Pour le 4096 je ne sais plus pourquoi je fais ainsi, ça me paraissait bien ahah vous pouvez le modifier comme bon vous semble c'est la taille du buffer donc plus le buffer sera grand et plus vous chargerez de grands blocs et normalement moins il y aura de sollicitations sur le fichier, le réduire à 1 fera qu'a chaque octet on se déplace dans le fichier et ça prend beaucoup de temps.

Si un char fait au moins 8bits on peut y mettre un nombre de 0 à 255 (256 possibilités) en non signé (unsigned char),
et un nombre de -128 à 127 en signé (char tout court) en fait ça fait sur du 7bits vu qu'un bit est utilisé pour le signe, et retrouve 128+127+zero = 256 possibilités
0
Bilow Messages postés 1193 Statut Membre 117
 
Je repasse un peu tard, mais
Merci beaucoup !
Vos explications me sont biens utiles pour d'autres projets où je dois lire des fichiers de tout type... :-)
0