@Yannshu : ça m'a l'air bon, mis à part que je trouve le code un peu trop compact, et que tu utilise des fonctions non-standard. (Enfin ça, ce n'est pas moi qui vais te le reprocher...)
@ttthebest : ça serait intéressant de valider un peu plus les entrées, et ton code ne marche pas sur des fichiers binaires.
Sinon, le code en lui même est assez clair.
Eh bien, en voilà un Rq : je suis débutant dans le sens où j'apprends tout seul et en parallèle avec une montagne de maths et de physique, je ne le suis pas dans le sens où je n'en suis plus à mes "débuts". Mais quand même
Mon algo principal pour coder avec un mot de passe :
int OpererFichier(FILE *fichierAOperer, FILE *fichierOpere, int tailleFichier)
{
if (!fichierAOperer || !fichierOpere)
return 0;
printf("Veuillez patienter : 0 %%");
int percent = 0,
lng=strlen(password),
k=0, i, j,
read;
char c[100];
for (i=0 ; (read=fread(c, 1, 100, fichierAOperer)) > 0 && i < tailleFichier ; i += 100)
{
for (j=0 ; j<read ; j++)
{
c[j] = c[j]^password[k];
k = (k+1)%lng;
}
fwrite(c, 1, read, fichierOpere);
if ((int)((i+1) / (tailleFichier * 0.01)) > percent)
{
percent = (i+1) / (tailleFichier * 0.01);
printf("\rVeuillez patienter : %d %%", percent);
}
}
return 1;
}
Où password est évidemment le mot de passe entré par l'utilisateur (une variable globale, car utilisée partout... y en a que deux ! )
Sinon, l'implémentation totale est ici (inclus tout le tralala d'interface, donc c'est assez long pour pas grand-chose...) :
#include <stdio.h>
#include <stdlib.h>
FILE* RecupererNomFichier(char chaine[], int taille);
void EntrerMotDePasse(char chaine[], int taille);
int OuiOuNon();
int RecupererTailleFichier(char nomFichier[]);
int Quit();
int FichierExiste(char nomFichier[]);
int OpererFichier(FILE *fichierAOperer, FILE *fichierOpere, int tailleFichier);
int EcrireSignature(FILE *fichierCrypte);
int Crypter();
int VerifierMotDePasse(FILE *fichier, char pwd[]);
int Decrypter();
int Operation(char nomFichierAOperer[], FILE *fichierAOperer, int tailleFichier, int ajouterSignature);
void viderBuffer();
char password[100] = "";
char signature[] = "TheSDZIsTheBestOne_[CokieForever]";
int main(int argc, char *argv[])
{
int done=0;
while (!done)
{
printf("CRYPT@LIAS : codage et decodage faible de petits fichiers\n\n1° Crypter\n2° Decrypter\n\nVeuillez choisir : ");
char c = 0, mode = 0;
do
{
c = getch();
if (c == '1' || c == '2')
{
printf("%c\b", c);
mode = c-'0';
}
else if (c == '\b')
printf(" \b");
} while (c != 13 || mode == 0);
if (mode == 1)
Crypter();
else Decrypter();
system("cls");
}
return EXIT_SUCCESS;
}
FILE* RecupererNomFichier(char chaine[], int taille)
{
char *p;
while (fgets(chaine, taille, stdin) == NULL);
if ((p=strchr(chaine, '\n')) != NULL)
*p = '\0';
else viderBuffer();
return fopen(chaine, "rb");
}
void EntrerMotDePasse(char chaine[], int taille)
{
char buffer[100] = "";
int i;
for (i=0 ; i<100 && (i<1 || buffer[i - 1] != 13) ; i++)
{
buffer[i] = getch();
if (buffer[i] != 13 && buffer[i] != '\b')
printf("*");
if (buffer[i] == '\b' && i > 0)
{
printf("\b \b");
i -= 2;
}
else if (buffer[i] == '\b' && i <= 0)
i--;
}
strncpy(chaine, buffer, taille);
return;
}
int OuiOuNon()
{
char c;
do
{
c = toupper(getch());
} while (c != 'O' && c != 'N');
printf("%c", c);
if (c=='O')
return 1;
else return 0;
}
int RecupererTailleFichier(char nomFichier[])
{
FILE *fichier = fopen(nomFichier, "r");
int t, p;
if (!fichier)
return -1;
p = ftell(fichier);
fseek(fichier, 0, SEEK_END);
t = ftell(fichier);
fseek(fichier, p, SEEK_SET);
fclose(fichier);
return t;
}
int Quit()
{
printf("\n\nAbandon de l'operation. Fichier non modifie.\n\nAppuyez sur une touche pour quitter... ");
getch();
return 0;
}
int FichierExiste(char nomFichier[])
{
FILE *fichier = fopen(nomFichier, "r");
if (fichier)
{
fclose(fichier);
return 1;
}
else return 0;
}
int OpererFichier(FILE *fichierAOperer, FILE *fichierOpere, int tailleFichier)
{
if (!fichierAOperer || !fichierOpere)
return 0;
printf("Veuillez patienter : 0 %%");
int percent = 0,
lng=strlen(password),
k=0, i, j,
read;
char c[100];
for (i=0 ; (read=fread(c, 1, 100, fichierAOperer)) > 0 && i < tailleFichier ; i += 100)
{
for (j=0 ; j<read ; j++)
{
c[j] = c[j]^password[k];
k = (k+1)%lng;
}
fwrite(c, 1, read, fichierOpere);
if ((int)((i+1) / (tailleFichier * 0.01)) > percent)
{
percent = (i+1) / (tailleFichier * 0.01);
printf("\rVeuillez patienter : %d %%", percent);
}
}
return 1;
}
int EcrireSignature(FILE *fichierCrypte)
{
if (!fichierCrypte)
return 0;
int lng=strlen(password),
k=0, i;
char c;
rewind(fichierCrypte);
for (i=0 ; signature[i] ; i++)
{
c=signature[i]^password[k];
fwrite(&c, 1, 1, fichierCrypte);
k = (k+1)%lng;
}
return 1;
}
int Crypter()
{
system("cls");
printf("Bienvenue dans Crypt@lias.\nCe logiciel va vous permettre de crypter faiblement vos fichiers\nafin de les proteger contre d'eventuelles intrusions.\n\n");
char nomFichierACrypter[1000];
FILE *fichierACrypter = NULL;
int tailleFichier;
printf("Veuillez d'abord entrer le nom du fichier a crypter\n(et eventuellement son adresse) :\n");
do
{
if ( !(fichierACrypter = RecupererNomFichier(nomFichierACrypter, 1000))
|| (tailleFichier = RecupererTailleFichier(nomFichierACrypter)) < 0 )
printf("\nCe fichier n'existe pas ou est inacessible.\nVeuillez en choisir un autre :\n");
} while (!fichierACrypter);
printf("\nLe fichier a ete ouvert avec succes.");
char buffer[100];
int done=0;
do
{
printf("\nVeuillez choisir un mot de passe : ");
EntrerMotDePasse(buffer, 100);
printf("\nConfirmez le mot de passe : ");
EntrerMotDePasse(password, 100);
if (strcmp(password, buffer))
printf("\n\nLes mots de passe sont differents.\nVeuillez recommencer...\n");
else done=1;
} while (!done);
printf("\n\nAVERTISSEMENT : en cas de perte de votre mot de passe, vos donnees\nseront impossible a recuperer. N'oubliez pas que les mots\nde passe sont sensibles a la casse.\n\n");
printf("Confirmez-vous le lancement ? (o/n) : ");
if (!OuiOuNon())
return Quit();
return Operation(nomFichierACrypter, fichierACrypter, tailleFichier, 1);
}
int VerifierMotDePasse(FILE *fichier, char pwd[])
{
if (!fichier)
return -1;
rewind(fichier);
char c, buffer[100];
int lng = strlen(pwd),
slng = strlen(signature),
k=0, i;
for (i=0 ; i<slng ; i++)
{
fread(&c, 1, 1, fichier);
buffer[i] = c^pwd[k];
k = (k+1)%lng;
}
return (!strcmp(buffer, signature));
}
int Decrypter()
{
system("cls");
printf("Bienvenue dans Crypt@lias.\nCe logiciel va vous permettre de decrypter vos fichiers precedemment encodes.\n\n");
char nomFichierADecrypter[1000];
FILE *fichierADecrypter = NULL;
int tailleFichier;
printf("Veuillez d'abord entrer le nom du fichier a crypter\n(et eventuellement son adresse) :\n");
do
{
if ( !(fichierADecrypter = RecupererNomFichier(nomFichierADecrypter, 1000))
|| (tailleFichier = RecupererTailleFichier(nomFichierADecrypter)) < 0 )
printf("\nCe fichier n'existe pas ou est inacessible.\nVeuillez en choisir un autre :\n");
} while (!fichierADecrypter);
printf("\nLe fichier a ete ouvert avec succes.\nVeuillez entrer votre mot de passe : ");
int done=0;
do
{
EntrerMotDePasse(password, 100);
if (!VerifierMotDePasse(fichierADecrypter, password))
printf("\n\nMot de passe incorrect.\nVeuillez recommencer... : ");
else done=1;
} while (!done);
printf("\n\nMot de passe correct.");
fseek(fichierADecrypter, strlen(signature), SEEK_SET);
return Operation(nomFichierADecrypter, fichierADecrypter, tailleFichier-ftell(fichierADecrypter), 0);
}
int Operation(char nomFichierAOperer[], FILE *fichierAOperer, int tailleFichier, int ajouterSignature)
{
if (!nomFichierAOperer || !fichierAOperer)
return 0;
char nomFichierTampon[1010];
sprintf(nomFichierTampon, "%s.tmp", nomFichierAOperer);
if (FichierExiste(nomFichierTampon))
{
printf("\n\nATTENTION !\nLe programme se prepare a ecraser le fichier suivant :\n%s\nContinuer ? (o/n) : ", nomFichierTampon);
if (!OuiOuNon())
return Quit();
}
FILE *fichierOpere = NULL;
do
{
if ((fichierOpere = fopen(nomFichierTampon, "wb+")) == NULL)
{
printf("\n\nErreur : Impossible d'ouvrir le fichier temporaire.\nReessayer ? (o/n) : ");
if (!OuiOuNon())
{
fclose(fichierAOperer);
return Quit();
}
}
} while (fichierOpere == NULL);
printf("\n\nOperation en cours...\n\n");
if (ajouterSignature)
EcrireSignature(fichierOpere);
OpererFichier(fichierAOperer, fichierOpere, tailleFichier);
fclose(fichierAOperer);
fclose(fichierOpere);
printf("\nOperation terminee avec succes.\n\nRemplacer l'original ? (o/n) : ");
if (OuiOuNon())
{
remove(nomFichierAOperer);
rename(nomFichierTampon, nomFichierAOperer);
}
printf("\n\nOperation terminee. Appuyez sur une touche.");
getch();
return 1;
}
void viderBuffer()
{
int c = 0;
while (c != '\n' && c != EOF)
c = getchar();
}
Lors du cryptage, je crypte en plus une chaine prédéterminée et je la place en tête du fichier de sortie.
Ainsi, lors du décryptage, pour vérifier si un mot de passe donné est bon, il suffit de décrypter les premiers caractères du fichier : si on retrouve la chaine prédéterminée, c'est que c'est bon (sauf si le mot de passe est plus grand que la chaine...)
(Bien entendu, à l'aide de la chaine prédéterminée et de sa version cryptée, on peut donc en déduire le mot de passe... Mais bon, c'est mieux que rien ! )
Bon, cet exercice étant sympa, j'ai voulu essayer de le faire.
J'en suis au 2°), mais je crois que j'ai un peu trafiqué l'énoncé ...
Voilà mon code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, const char * argv[]) {
int i = 0, key = 141;
int crypt[10000] = {0};
char uncrypt[10000] = "", title[100] = "";
printf("\nTitle :\t");
fgets(title, sizeof(title), stdin);
printf("\nText :\n\t");
fgets(uncrypt, sizeof(uncrypt), stdin);
int lenght = strlen(uncrypt);
for (i = 0; i <= lenght; i++)
{
crypt[i] = uncrypt[i]^key;
}
FILE* fichier = NULL;
fichier = fopen(title, "w+");
for(i = 0; i <= lenght; i++)
{
fprintf(fichier, "%.2x\n", crypt[i]);
}
fclose(fichier);
return 0;
}
Pour l'instant pas de fonction ni rien, j'essaye d'y arriver d'abord.
Voilà le problème : je demande à l'utilisateur un titre, puis du texte.
Avec le titre, je crée un fichier texte et à l'intérieur de ce fichier, je place le texte codé :
crypt[i] = uncrypt[i]^key
J'ai donc sur chaque ligne de mon fichier chaque caractère du texte de l'utilisateur codé. Par contre, je ne sais pas comment récupérer ces caractères pour ensuite les décoder... Quelqu'un pourrait-'il m'aider ?
Merci à tous !
Personne n'a d'idée, vraiment ?
J'ai mon tableau de int, je le copie dans le fichier .txt mais après si je récupère j'ai une chaîne de caractère... Et ça va plus pour retranscrire !
Quelqu'un sait comment réussir ? Ou comment procéder autrement ? Merci à tous !
Passe par les fonctions d'écriture/lecture en mode binaire, avec fwrite/fread.
Ici, tu écris le caractère en valeur hexadécimale, hors il faut le stocker directement au format binaire si tu ne veux pas t'embêter avec des conversions inutiles.
Et pourquoi utilise-tu un tableau d'int ? Un tableau de char n'irait pas ?
Mmh, tu pourrais me filer le prototype des fonctions fwrite et fread s'il te plait ?
Et comment passer de 1001011 à 'b', par exemple ?? (c'est du pif hein ).
Mmh, j'ai cherché sur pas mal de trucs, et ça à rien donné de bon !
Avec fwrite, on peut écrire sur un fichier .txt ? Mmh...
Et sinon, tu pourrais m'orienter un peu sur cette fonction bizarre particulière ? (bien qu'elle soit totalement normale, j'avais envie de mettre ça !)
Salut, j'ai pas vraiment respecté les prérogatives de sortie, mais j'ai un souci.
J'ai fait mon code (simpliste), et quand je vois vos codes à vous, j'ai peur °_°
Est-ce que vous pouvez m'expliquer comment ça se fait que j'ai l'impression de m'être planté?
#include <stdio.h>
#include <stdlib.h>
#define TYP_LEN 50
unsigned char XOR(unsigned char letter, unsigned char key)
{
return letter^key;
}
int main()
{
int i=0, j=0;
unsigned char xor_key=0x1a;
unsigned char sentence[TYP_LEN]={0};
unsigned char crypt_sentence[TYP_LEN]={0};
printf("Entrez une phrase : ");
fgets((char*)sentence,TYP_LEN,stdin); //Trouve-t-on un moyen moins moche pour que
//le param de fgets soit accepté?
for(i=0;i<TYP_LEN && sentence[i]!='\n';++i)
crypt_sentence[i]=XOR(sentence[i],xor_key);
for(j=0;j<i;++j)
printf("%.2X ",sentence[j]);
printf("\n\n");
for(j=0;j<i;++j)
printf("%.2X ",crypt_sentence[j]);
printf("\n\n");
return 0;
}
Bon j'ai toujours pas compris les codes compliqués d'en haut, mais je me permet de vous soumettre celui-là, si je peux l'améliorer de quelque maniète que ce soit, je vous en prie, faites moi grandir
Autre détail, j'ai trouvé sur le net que le ++i était plus rapide que le i++ (le bien nommé), si quelqu'un sait à quelle amplitude il est plus rapide et si ça sert vraiment, je suis toute ouïe
@che : faire un code compact ne le rend pas meilleur...Mais sinon ça à l'air correct.
Oui en effet L'envi de faire moins de ligne. J'édite.
@ quentin-fait-du-c: je pense pas que la fonction XOR soit nécessaire et aussi une variable pour la clé est peut-être exagéré, aussi tu pourrais faire un seul tableau de char. Mais ton code est correcte, il fait ce que l'on veut et il n'a pas d'erreur.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles- ♡ Copying is an act of love.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
Objectif Zéro Bug - le test logiciel professionnel | L'électronique de zéro | Tableaux & pointeurs | Pointeurs sur fonctions | Lecture/écriture binaire
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.