IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

__int64 XOR et crypto [Langage/Algorithme]


Sujet :

C++Builder

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Par défaut __int64 XOR et crypto
    Bonjour à tous,

    je suis en train de coder une partie de classe permettant de crypter/décrypter des données de manière très basique avec un simple XOR.

    Pour se faire je test sur un simple fichier pour commencer ( et non directement sur des frames réseau via liaison TCP/IP ).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    void C_PWI_Engine::Decrypter(AnsiString Nom_Fichier)
    {
    	FILE *Fich;
    
    	Fich = fopen(Nom_Fichier.c_str(),"r+b");
    	unsigned long int SizeOfBuffer = 4096;
    	unsigned __int64 *Int64_Buff;
    	unsigned __int64 Int64_Clef=0x1122334455667788;
    	char *Buffer;
    	Buffer = new char[SizeOfBuffer];
    
    	for (unsigned long int i = 0; i < Filesize(Fich); i += SizeOfBuffer)
    	{
    		fseek(Fich,i,SEEK_SET);
    		fread(Buffer,SizeOfBuffer,1,Fich);
    
    		/* Crypte ou decrypte ( involutif ) */
    
    		for (unsigned long int j = 0; j < SizeOfBuffer; j++)
    		{
    			Int64_Buff = (unsigned __int64*) ((void) (Buffer+j));
    			*Int64_Buff = *Int64_Buff ^ Int64_Clef;
    		}
    
    		/* ecrit vers fichier destination */
    		fseek(Fich,i,SEEK_SET);
    		fwrite(Buffer,SizeOfBuffer,1,Fich);
    	}
    	fclose(Fich);
    	delete Buffer;
    }
    Problème : c'est lent.

    Du coup je me suis dit qu'en déclarant un __int64 je devrais théoriquement pouvoir utiliser toute la puissance du processeur 64bits et de son opérateur XOR ( qui doit être si mes souvenirs sont bons plus rapide qu'un ADD ou toute autre opération ).

    sauf que j'ai un soushi avec la ligne en rouge.
    Comment peut-on faire pointer un __int64 sur un tableau d'octets (de char) ?
    Je sais que c'est possible car je l'ai déjà fait par le passé mais je ne me rappelle plus de la syntaxe exacte ( reinterpret_cast ? )


    Seconde question : l'utilisation d'un __int64 est-elle un plus ou le compilateur va-t-il de toute façon reconvertir derrière (cas d'une machine 32bits) ??

    Merci d'avance pour vos réponses et vos conseils sur l'algorithme que vous utiliseriez pour avoir une vitesse maximale !

  2. #2
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2005
    Messages
    401
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 401
    Par défaut
    Hello,

    Pour ton problème de cast, tu es à une étoile près:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	Int64_Buff = (unsigned __int64*) ((void*) (Buffer+j));
    Sinon, le void (étoile ou pas) ne sert à rien, ceci a l'air de marcher aussi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	Int64_Buff = reinterpret_cast<unsigned __int64*>(Buffer+j);

  3. #3
    Membre très actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Par défaut
    Arf ... merci beaucoup, décidément j'ai besoin de vacances moi

    Effectivement je viens de tester ça marche je me retrouve bien avec le pointeur __int64 à l'adresse de mon tableau de char.

    Concernant l'algo optimisée ( ou pas ) avec les __int64, si quelqu'un a des infos je suis tout de même preneur.

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    Question, en ne faisant pas de calcul, juste en mettant ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
                    fseek(Fich,i,SEEK_SET);
    		fread(Buffer,SizeOfBuffer,1,Fich);
    		fseek(Fich,i,SEEK_SET);
    		fwrite(Buffer,SizeOfBuffer,1,Fich);
    Quel est la différence de temps avec le XOR ?
    Tu auras le temps réelle de cette opération !
    Car la tu lis et écris dans le même fichier, le Seek n'est-il pas une opération un peu lente ?
    Ecrire dans un fichier temporaire serait plus rapide à mon avis !

    sinon ta boucle, je modifierais le pas, cela suffit !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
                    for (unsigned long int j = 0; j < SizeOfBuffer; j += sizeof(__int64))
    		{
    			Int64_Buff = (unsigned __int64*)(Buffer + j);
    			*Int64_Buff = *Int64_Buff ^ Int64_Clef;
    		}
    ou par tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
                    for (unsigned long int j = 0; j < SizeOfBuffer / sizeof(__int64); j++)
    		{
    			Int64_Buff = &((unsigned __int64*)Buffer)[j];
    			*Int64_Buff = *Int64_Buff ^ Int64_Clef;
    		}
    tient un petit comparatif

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    {
      char *Buffer = new char[6];
      *((short*)Buffer) = 33833; // 1000 0100 0010 1001 // 8429 -> „) -> LE : )„
      *((short*)(Buffer + sizeof(short))) = 37446; // 1001 0010 0100 0110 // 9246 -> ’F -> LE : F’
      *((short*)(Buffer + 2 * (sizeof(short)))) = 101; // 0000 0000 0110 0101 // 0065 -> zero e -> LE : e zero
      ShowMessage(Buffer); // )„F’e
      delete [] Buffer;
     
      Buffer = new char[6];
      ((short*)Buffer)[0] = 33833; // 1000 0100 0010 1001 // 8429 -> „) -> LE : )„
      ((short*)Buffer)[1] = 37446; // 1001 0010 0100 0110 // 9246 -> ’F -> LE : F’
      ((short*)Buffer)[2] = 101; // 0000 0000 0110 0101 // 0065 -> zero e -> LE : e zero
      ShowMessage(Buffer); // )„F’e
      delete [] Buffer;
    }


    Sinon change la forme du buffer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    __int64* Buffer = new __int64[SizeOfBuffer / sizeof(__int64)];
    Cela sera plus facile à parcourir !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
                    for (unsigned long int j = 0; j < SizeOfBuffer / sizeof(__int64); j++)
    			Buffer[j] ^= Int64_Clef;
    Faudra penser à la phase finale, si tu ne lit que 1 à 7 octet dans le fichier et non 8 !




    Tu aurais faire ton code sur un TStream ainsi il aurait été compatible avec un TFileStream, un TMemoryStream utilisé dans le cas du TCP\IP

    Pour les performances, utilise NativeUInt, un type de XE2, il sera en 32 ou 64bits selon l'architecture, avec sizeof tu pourras gérer sa longueur facilement !

    Enfin attention ton Delete ! new[] -> delete[] !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre très actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Par défaut
    Merci pour ton aide Shai.

    Alors oui je mesure effectivement le temps total, donc fseek/fread + "XORage"

    je vais mettre des gettick pour séparer un peu ces temps et pouvoir analyser le temps uniquement du au xor.

    Le NativeUInt j'ai jamais essayé, je vais voir ce que ça donne et utiliser une TStream aussi peut-etre tant qu'à faire.

    (Joli oublie de delete sinon en effet )

  6. #6
    Membre très actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Par défaut
    J'ai avancé un peu, pas encore testé en stream je reste sur le fichier pour l'instant.

    En mettant le fichier complet (40Mo) en buffer, j'arrive à avaler les 40 Mo en moins d'une seconde ... wow !

    C'était donc bien l'accès disque qui était le plus long.

    Par contre 2 questions concernant le sizeof(__int64) : il me retourne 4 alors que la taille du __int64 est 8 octets !

    Du coup j'ai ajouté un 2* dans le code mais j'aimerais bien comprendre pourquoi ??

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    void C_PWI_Engine::Decrypter(AnsiString Nom_Fichier)
    {
    	clock_t start, end;
    	start = clock();
     
    	/* Definir la clef de cryptage 64 bits */
    	unsigned __int64 Int64_Clef=CLEF_DE_CRYPTAGE;
     
    	/* Ouvrir le fichier */
    	FILE *Fich;
    	Fich = fopen(Nom_Fichier.c_str(),"r+b");
    	if (Fich != NULL)
    	{
     
     
    		/* Recuperer la taille du fichier */
    		unsigned long int FileSize = Filesize(Fich);
     
    		/* Creer un buffer pour stocker le fichier en memoire */
    		unsigned __int64 *Int64_Buff;
    		char *Buffer;
    		Buffer = new char[FileSize+8]; // +8 histoire de ne pas risquer de buffer overflow
     
    		/* Charger le programme en mémoire */
    		fseek(Fich,0,SEEK_SET);
    		fread(Buffer,FileSize,1,Fich);
     
    		/* Crypter ou decrypter ( involutif ) */
    		unsigned long int i=0;
    		while(i<FileSize)
    		{
    			Int64_Buff  = (unsigned __int64*) (Buffer+i);
    			*Int64_Buff ^= Int64_Clef;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	        	i += 2*sizeof(Int64_Buff);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    		}
     
    		/* enregistrer les modifications dans fichier destination */
    		fseek(Fich,0,SEEK_SET);
    		fwrite(Buffer,FileSize,1,Fich);
     
    		/*  fermer le fichier et supprimer le buffer */
    		fclose(Fich);
    		delete Buffer;
    		Buffer = NULL;
     
    		end = clock();
    		AnsiString txt= "temp écoulé = ";
    		txt = txt + IntToStr( (__int64) ((end - start) / CLK_TCK) ); // sortie = 1s sur une brouette
    		txt = txt + "s";
     
    		ShowMessage(txt);
    	}
    }
    Sinon concernant le type NativeUInt impossible à utiliser : je crois qu'avec le 2010 il n'est effectivement pas disponible, il va falloir que j'installe l'update XE2.

    Ha oui et j'ai géré la fin de fichier en mettant un Buffer = new char[FileSize+8];
    Les derniers octets à crypter seront donc possiblement des octets bidons mais ça évite d'avoir à gérer la fin de fichier.

  7. #7
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 081
    Par défaut
    je te garanti que sizeof(__int64) == 8, tu n'aurais pas fait un sizeof sur un __int64* et la oui, un pointer sous D2010 c'est toujours 4 !

    EDIT :
    Ah ben, si je viens de voir l'extrait de code unsigned __int64 *Int64_Buff;.

    Evidemment sizeof(Int64_Buff) == 4 et sizeof(*Int64_Buff) == 8
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  8. #8
    Membre très actif Avatar de Argol_Medusa
    Homme Profil pro
    Ingénieur Radiofréquences
    Inscrit en
    Août 2005
    Messages
    208
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Radiofréquences
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 208
    Par défaut
    Bingo c'est ça !

    Merci Shai !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Crypto]JCE no provider ?
    Par leiaconcept dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 01/04/2005, 04h45
  2. [Crypto] Bouncy Castle Provider
    Par mush_H dans le forum Sécurité
    Réponses: 3
    Dernier message: 09/01/2005, 10h38
  3. Pb avec __int64
    Par philistase dans le forum MFC
    Réponses: 2
    Dernier message: 29/12/2004, 17h07
  4. [Crypto] Besoin d'aide de cryptage en java
    Par djyb2003 dans le forum Sécurité
    Réponses: 3
    Dernier message: 08/03/2004, 18h13
  5. technique du XOR
    Par microseb dans le forum C++Builder
    Réponses: 2
    Dernier message: 09/08/2003, 23h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo