Question sur lecture fichier

Question sur lecture fichier - C - Programmation

Marsh Posté le 19-04-2012 à 17:37:41    

Bonjour à tous, et merci d'avance de votre lecture et de votre potentielle aide.
 
Je cherche à coder un prog cryptographique en C, l'AES. Ma question ne se tourne pas vers l'AES en lui-même, mais en son utilisation.
 
En effet, je cherche à le tester sur un fichier texte. Dans ce fichier texte, il y a des retour à la ligne, \n.
 
Je dois lire mon fichier, le stocker d'une certaine façon par block de caractère. Pour cela, je lit mon fichier à l'aide de fgetc. Cependant, il ne lit pas les \n comme étant un seul caractère, mais '\', puis 'n' ( ce qui me parait logique vu que fgetc lit caractère par caractère ).
 
J'ai traité le cas à l'aide de if, ce qui a solutionné mon problème, mais pas ma curiosité !  
 
Je vous demande donc, s'il existe un moyen de lire un fichier, et de ne pas avoir ce problème, càd lire les \n comme étant un seul caractère, sans passer par des :
 
if ( carac == 92 )  
   if ( carac == 'n')  etc etc....
 
Je ne suis pas spécialement bon en C, je ne connais pas tout les moyen de lire des fichiers.
 
Je vous remercie d'avance de vos réponses !
 

Reply

Marsh Posté le 19-04-2012 à 17:37:41   

Reply

Marsh Posté le 19-04-2012 à 17:43:32    

C'est très étrange que le fgetc() retourne '\' puis 'n'.
 
- Soit le fichier ne contient pas de vrais retours à la ligne.
- Soit le fichier aurait été ouvert en mode texte au lieu du mode binaire.
- Soit le fgetc() retournerait deux caractères, mais ce serait 0x0D et 0x0A ou l'inverse, et non pas '\' et 'n'. Voir http://fr.wikipedia.org/wiki/Fin_de_ligne

Reply

Marsh Posté le 19-04-2012 à 18:03:35    

Ah excuse moi j'ai oublié de préciser, en effet le fichier le contient pas de vrai retour à la ligne, mais réellement des \n.
 
D'ailleurs autre fait étrange, j'ai l'impression que mon petit code compte mal le nombre de caractère...
 
ça me donne le bon résultat pour les environs 10000 premiers caractère, mais quand je teste les 11343 caractères, mon prog me retourne 11345.
 
Le fichier total contient 143324 caractères , mais mon prog retourne 143437 T_T.
 
Si quelqu'un à le courage de lire les lignes de code qui permettent de compter le nombre de ligne, je vais le copier ici ( c'est pas grand ça fait 50 lignes, mais bon c'est toujours un peu embêtant à lire. )
 
 
Edit : je veux stocker les valeurs des caractères en Hexa dans un tableau, y a t'il un moyen plus efficace que de compter le nombre de caractère, puis faire de l'allocation dynamique pour créer un pointeur de taille ( nombre de caractère )*( sizeof int ) , puis de reparcourir le fichier en recopiant?


Message édité par Sunk le 19-04-2012 à 18:12:46
Reply

Marsh Posté le 19-04-2012 à 19:58:08    

Ben, tu vas directement à la fin de ton fichier via un seek, tu récupère la position, et t'as la taille du fichier.
Comme ça tu peux allouer ton tableau (qui se doit d'être un tableau de char, car un char = un byte) et être sûr que ça ne dépassera pas


---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 19-04-2012 à 20:02:19    

Merci pour le seek, ça va m'éviter une boucle.
 
Par contre je ne comprend pas pourquoi le tableau doit être de type char, car au final, c'est des entiers entre 0 et 255, enfin des bytes quoi.
 
Je ne comprend pas vraiment l'intérêt, si on peut m'expliquer  !!   Ma formation est surtout mathématique, on a pas mal de lacune en infos et en prog qu'on doit essayer de combler par nous même.

Reply

Marsh Posté le 19-04-2012 à 20:12:28    

Un char, c'est un entier signé sur 8bits (un octet/byte)
 
La particularité, c'est que lors de l'affichage d'une variable de type char, le programme se réfère à la table ASCII pour afficher, genre par exemple, si la valeur c'est '55', ça affichera un '7', si c'est 57, ça fera un '9', 33 fera un espace, etc etc..
 
Mais toujours est-il que c'est un entier (tu peux faire des opération d'addition, soustraction, etc, etc)
 
Si tu veux afficher la valeur décimale d'un char, faut caster en int lors de l'affichage ( (int)tavariableenchar )
 
Bref, si tu stocke les valeurs de tes lettres de ton fichier dans un tableau de int, tu auras 3 cases mémoires inutilisé par case de ton tableau.
Après, je sais pas si c'est sensé supporter des caractères spéciaux (genre les charactères japs), dans ce cas c'est wchar un truc comme ça qu'il faut


---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 19-04-2012 à 20:21:40    

Ok je vois.

 

Edit : donc je peux stocker des char car je sais que mes nombres ne vont pas dépasser 255.

 

Je vais expliquer un peu le fonctionnement de mon programme, si tu peux m'aider pour mieux savoir comment gérer mes données.

 

J'ai un texte quelconque.

 

Je le découpe en blocs de 128 bits, donc en blocs de 16 caractères.

 

L'entré de ma fonction est un bloc de 128 bits, ainsi que ça sortie. On effectue des opérations sur ces blocs de bits, au niveau des bytes ( 1 bloc = 16 bytes quoi ). On doit se servir de l'addition ( c'est le  XOR ) , et de la multiplication dans GF256.

 

Je représente mes bytes en hexa, mais pour faire le XOR et la multiplication, je dois passer par la représentation binaire.

 

Pour l'instant j'étais parti sur l'idée de : prendre mon texte, et recopier toutes les valeurs ASCII dans un tableau. Or j'ai besoin de la valeur en hexa des bytes ( ou en binaire ). Pour ça, je comptais stocker chaque byte dans un tableau de taille 2 ( genre f3 = [15,3] ).

 

Je sais que ma méthode va marché, mais j'ai l'impression qu'il y a moyen de faire bien plus efficace.


Message édité par Sunk le 19-04-2012 à 21:34:15
Reply

Marsh Posté le 20-04-2012 à 00:30:57    

Pourquoi t'as besoin de la valeur hexa/binaire ?
Le xor agit directement sur les bits, genre si t'as ça :

 

2^3, ton programme calculera ça  0010 ^ 0011 -> 0001, tu auras donc "1" en sortie.

 

En c t'as les opérateurs qui agissent sur des booléennes (&& / || / ^^), et t'as ceux qui agissent sur les bits (&, | , ^)


Message édité par Terminapor le 20-04-2012 à 00:32:06

---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 20-04-2012 à 00:47:42    

En fait c'est pour la multiplication sur GF256 que je ne sais pas coder sinon.
 
Que font ces opérateurs?  
 
Edit : merci de ta réponse


Message édité par Sunk le 20-04-2012 à 00:55:50
Reply

Marsh Posté le 20-04-2012 à 01:10:19    

Bonsoir,
 
Tout cela m'a l'air un petit peu confus... Tu m'as l'air d'oublier que l'affichage hexa en caractères ASCII de ton texte ne sont que des représentations de tes données, et que ton processeur travaille déjà en binaire et possède déjà une bonne partie des instructions nécessaires.
 
Tu vas avoir tout à gagner à utiliser les opérations binaires disponibles en C, notamment pour un XOR, l'opérateur s'écrit "^":
 
int a = 6 ^ 3;
 
printf("%d", a); /* Affiche 5 */
 
Plus d'info sur les opérateurs C: http://www.commentcamarche.net/contents/c/cop.php3
 
Descriptif des formats d'affichage, qui te serviront certainement au cours de ton développement (%x est ton ami):
http://www.cplusplus.com/reference [...] io/printf/
 
Note que les processeurs actuels travaillent généralement sur des mots de 64 bits, tu as donc possiblement à gagner à exploiter cette architecture (mais seulement dans un second temps, quand tu auras posé la base).
 
#include <stdint.h>
 
typedef struct {
    uint64_t tab[2];
} block128_t;
 
static inline block128_t block128_xor(block128_t b1, block128_t b2)            
{                                                                              
    return (block128_t){                                                        
        .t = {                                                                  
            b1.t[0] ^ b2.t[0],                                                  
            b1.t[1] ^ b2.t[1]                                                  
        }                                                                      
    };                                                                          
}
 
Dans cet exemple, tu effectue l'addition de deux mots de 128 bits en seulement deux opérations binaires.

Reply

Marsh Posté le 20-04-2012 à 01:10:19   

Reply

Marsh Posté le 20-04-2012 à 01:21:31    

Pour la multiplication en GF(256), j'ai trouvé ça:
http://www.cs.utsa.edu/~wagner/laws/FFM.html
 
D'ailleurs, il y un algo de multiplication GF(256) en pseudo-java, dont tu peux éventuellement t'inspirer pour ton programme C:
 

Code :
  1. public byte FFMul(unsigned byte a, unsigned byte b) {
  2.    unsigned byte aa = a, bb = b, r = 0, t;
  3.    while (aa != 0) {
  4.       if ((aa & 1) != 0)
  5.          r = r ^ bb;
  6.       t = bb & 0x80;
  7.       bb = bb << 1;
  8.       if (t != 0)
  9.          bb = bb ^ 0x1b;
  10.       aa = aa >> 1;
  11.    }
  12.    return r;
  13. }


Message édité par __werz le 20-04-2012 à 13:40:46
Reply

Marsh Posté le 20-04-2012 à 01:23:59    

Merci beaucoup de ton aide.
 
Je crois avoir trouvé mon bonheur dans les opérateur de décalage de bits...
 
En effet, la multiplication que je cherche reviens à faire des XOR et des décalages de bits dans un octet.
Je ne m'y connais pas beaucoup en C, j'ai tout le truc mathématique dans la tête, mais je ne savais pas comment le travailler en C.
 
Je vais lire tout ça de manière plus approfondie :).
 
Si tu veux connaître l'opération que je devais faire,  en fait on considère qu'un octet est un polynôme , un élément du corps fini F256.
 
L'octet b7b6b5b4b3b2b1b0 est représenté par b7 * X^7 + b6*x^6 + ... +b1*X + b0.
 
Donc par exemple, multiplier par X, qui est représenté par l'octet  00000010, revient à faire un décalage vers la gauche, puis un XOR ( car c'est un truc de maths.. )
 
Donc multiplier par n'importe quel octet revient à faire des XOR et des multiplication, je crois que le fait de pouvoir décaler les bits directement va améliorer grandement mon programme... Merci !
 
Edit : j'étais en train de posté ce message avant de voir ton dernier message, ceci était exactement ce que je cherchais, je savais bien qu'il y avait moyen de faire tout ça en travaillant directement sur les bits... Merci encore!


Message édité par Sunk le 20-04-2012 à 01:51:00
Reply

Marsh Posté le 21-04-2012 à 00:45:01    

Bonsoir,
 
Je suis content que ces quelques références aient pu t'aider. J'ai cherché à comprendre un peu GF(256), pour l'instant, ça m'a surtout l'air un peu magique car je n'ai pas fait de vraies maths depuis longtemps, il faudra que je reprenne ça à tête reposée.
 
N'hésite pas à poster ton travail quand il sera un peu plus avancé, ça m'intéresse et ce sera l'occasion de rendre le code un peu plus carré si nécessaire.

Reply

Marsh Posté le 21-04-2012 à 21:28:37    

Pas de problème pour t'envoyer le source, j'ai quasi tout fini.......
 
Mais j'ai un dernier problème, qui je crois est le dernier rempart à la finalisation de mon AES en mode CTR.
 
je vais l'expliquer simplement cette fois :  
 
j'ai un problème avec le caractère Ascii 26, qui se comporte comme un  EOF !
 
J'écris dans un fichier, à l'aide d'une fonction, le caractère ascii 26, suivit de "test" :
 
Je fais ça en faisant fprintf( fichier , "%ctest",26);
 
j'ouvre ce fichier, jvois bien écris : "->test" ( -> c'est la flèche représenté par l'ascii 26 ).
 
Ensuite, je teste de lire ce fichier caractère par caractère avec fgetc.
 
je fais le code suivant : ( en ajoutant tout ce qu'il faut avant bien entendu )
 
Carac = fgetc(fichier);
 
while ( Carac != EOF )
{
printf("%c",Carac);
Carac = fgetc(fichier);
 
}
 
Et résultat, la lecture s'arrête direct, comme si le premier caractère valait EOF, je rentre pas dans le while !
 
Edit : Pour GF256, il te faut des notions d'algèbre ( la vrai, pas l'algèbre linéaire ), et plus principalement dans les corps finis.

Message cité 1 fois
Message édité par Sunk le 21-04-2012 à 21:30:24
Reply

Marsh Posté le 21-04-2012 à 22:28:08    

Problème solve, je devais ouvrir mon fichier en mode binaire...

Reply

Marsh Posté le 23-04-2012 à 02:05:56    

Sunk a écrit :


Edit : Pour GF256, il te faut des notions d'algèbre ( la vrai, pas l'algèbre linéaire ), et plus principalement dans les corps finis.


 
C'est vieux mais j'en ai un peu (des notions). A tête reposée, j'ai fini par comprendre dans les grandes lignes, du coup j'ai codé la multiplication et la division en me basant sur une table logarithmique, elle même basée sur du code générée à l'aide de l'algo de multiplication basique. En revanche, je me suis arrêté là car j'avais un peu la flemme de continuer, mais j'ai appris des trucs :) .

Reply

Marsh Posté le 23-04-2012 à 03:33:33    

très bien ! J'ai moi même utilisé les tables crée à l'aide de l'algo de multiplication du dessus. L'utilisation des tables log et exp rapportent un gain de compléxité assès grand.
 
J'ai terminé de codé l'AES, j'ai utilisé le mode CTR pour le chiffrage.
 
Si tu veux en savoir plus, ou si tu veux le code source, envois moi un mail.
 
s*nk*mp*r*@hotmail.com
[Pas de mail en clair sur le forum! c'est pas comme si vous ne receviez déjà pas suffisamment de spam]


Message édité par gilou le 25-04-2012 à 10:58:29
Reply

Marsh Posté le 23-04-2012 à 04:10:19    

D'ailleurs, si tu as des chose à redire sur le code n'hésite pas, je suis encore un débutant en prog :).

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed