Aes: chiffrage et déchiffrage de fichiers

Soyez le premier à donner votre avis sur cette source.

Snippet vu 12 686 fois - Téléchargée 30 fois

Contenu du snippet

Code qui implémente l'algorithme de chiffrage AES que j'ai aussi posté.
Il présente un méni que permet de faire des opérations de chiffrage, de déchiffrage, de calcul de taille,etc.

Le chiffrage se fait avec une clé de 128 bits qui est matérialisée par 16 caractères aléatoires que vous entrez au clavier.
Il possible de chiffrer n'importe quel type de fichier (.txt, .jpeg, .mpeg,etc...)

Bonne utilisation!

Source / Exemple :


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
unsigned char rcon(int i)

	{
	int p;
	unsigned char j=1;

	for (p = 0; p < i - 1; p++)
		j = j*2;
	return j;
	}

unsigned char sub_s_box(unsigned char c, unsigned char cmd)

	{
	int i,nb_1 = 0;
	unsigned char s_box[8];
	unsigned char temp[8];
	unsigned char r[8];

	if (cmd == 'c')
		{
		s_box[0] = 143;
		s_box[1] = 199;
		s_box[2] = 227;
		s_box[3] = 241;
		s_box[4] = 248;
		s_box[5] = 124;
		s_box[6] = 62;
		s_box[7] = 31;
		}
	else
		{
		s_box[0] = 37;
		s_box[1] = 146;
		s_box[2] = 73;
		s_box[3] = 164;
		s_box[4] = 82;
		s_box[5] = 41;
		s_box[6] = 148;
		s_box[7] = 74;
		}

	for (i = 0; i < 8; i++) temp[i] = s_box[i] & c;

	for (i = 0; i < 8; i++)
		{
		nb_1=0;
		do
			{
			if (temp[i] % 2 != 0)
				{
				temp[i] -= 1;
				nb_1++;
				}

			temp[i] /= 2;
			} while (temp[i]>0);

		r[i] = nb_1 % 2;
		}

	return (r[0]*rcon(8) + r[1]*rcon(7) + r[2]*rcon(6) + r[3]*rcon(5) + 
r[4]*rcon(4) + r[5]*rcon(3) + r[6]*rcon(2) + r[7]*rcon(1));
	}

unsigned char multi(char a, char b)

	{
	int bb[5] = {0,0,0,0,0}, p = 0, intemp;
	unsigned char temp[5];
	temp[0] = b;

	do
			{
			if (temp[0] % 2 != 0)
				{
				temp[0] -= 1;
				bb[p] = 1;
				}

			p++;
			temp[0] /= 2;
			} while (temp[0] > 0);

	temp[0] = a;
	temp[1] = a;

	for(p = 1; p < 5; p++)	//on considére b de la forme 0x ou 1x
			{
			intemp = temp[p] * 2;
			if (intemp > 255) temp[p] = (intemp - 256) ^ 27;
			else temp[p] = intemp;
			if (p < 4) temp[p + 1] = temp[p];
			}

	for(p = 0; p < 5; p++)
			{
			if (bb[p] == 0) temp[p] = 0;
			}

	return temp[0] ^ temp[1] ^ temp[2] ^ temp[3] ^ temp[4];
	}

int expand_key(unsigned char key[4*4], unsigned char w[4*4*11])

	{
	int i,j;
	unsigned char temp;

	for(i = 0; i < 16; i++)
		w[i] = key[i];

	for(i = 16; i < 4*4*11; i++)
		{
		if (i % 16 < 4)
			{
			j = i % 4;
			if (j == 3) temp = w[i - 7];
			else temp = w[i - 3];
			temp = sub_s_box(temp, 'c');
			if (i % 16 == 0) temp = temp ^ rcon(i/16);
			}
		w[i] = w[i - 16] ^ temp;
		}

	return 0;
	}

int select_key(unsigned char expanded_key[4*4*11], unsigned char 
round_key[4][4], int round)

	{
	int i,j;

	for(i = 0; i < 4; i++)
			{
			for(j = 0; j < 4; j++)
					{
					round_key[j][i] = expanded_key[(round * 16) + (4 * i) + j];
					}
			}

	return 0;
	}
	
	

int byte_sub(unsigned char state[4][4], unsigned char cmd)

	{
	int i,j;

	for (i = 0; i < 4; i++)
		{
		for (j = 0; j < 4; j++)
			{
			if(cmd == 'd') state[i][j] ^= 198;
			state[i][j] = sub_s_box(state[i][j], cmd);
			if(cmd == 'c') state[i][j] ^= 198;
			}
		}

	return 0;
	}

int shift_row(unsigned char state[4][4], unsigned char cmd)

	{
	unsigned char temp;

	if (cmd == 'c')
		{
		temp = state[1][0];
		state[1][0] = state[1][1];
		state[1][1] = state[1][2];
		state[1][2] = state[1][3];
		state[1][3] = temp;

		temp = state[2][0];
		state[2][0] = state[2][2];
		state[2][2] = temp;
		temp = state[2][1];
		state[2][1] = state[2][3];
		state[2][3] = temp;

		temp = state[3][3];
		state[3][3] = state[3][2];
		state[3][2] = state[3][1];
		state[3][1] = state[3][0];
		state[3][0] = temp;
		}
	else
		{
		temp = state[1][3];
		state[1][3] = state[1][2];
		state[1][2] = state[1][1];
		state[1][1] = state[1][0];
		state[1][0] = temp;

		temp = state[2][0];
		state[2][0] = state[2][2];
		state[2][2] = temp;
		temp = state[2][1];
		state[2][1] = state[2][3];
		state[2][3] = temp;

		temp = state[3][0];
		state[3][0] = state[3][1];
		state[3][1] = state[3][2];
		state[3][2] = state[3][3];
		state[3][3] = temp;
		}

	return 0;
	}

int mix_column(unsigned char state[4][4], unsigned char cmd)

	{
	int i,j;
	unsigned char temp[4][4];

	for (i = 0; i < 4; i++)
		{
		for (j = 0; j < 4; j++) temp[i][j] = state[i][j];
		}

	if (cmd == 'c')
		{
		state[0][0] = multi(temp[0][0],2) ^ multi(temp[1][0],3) ^ 
multi(temp[2][0],1) ^ multi(temp[3][0],1);
		state[1][0] = multi(temp[0][0],1) ^ multi(temp[1][0],2) ^ 
multi(temp[2][0],3) ^ multi(temp[3][0],1);
		state[2][0] = multi(temp[0][0],1) ^ multi(temp[1][0],1) ^ 
multi(temp[2][0],2) ^ multi(temp[3][0],3);
		state[3][0] = multi(temp[0][0],3) ^ multi(temp[1][0],1) ^ 
multi(temp[2][0],1) ^ multi(temp[3][0],2);

		state[0][1] = multi(temp[0][1],2) ^ multi(temp[1][1],3) ^ 
multi(temp[2][1],1) ^ multi(temp[3][1],1);
		state[1][1] = multi(temp[0][1],1) ^ multi(temp[1][1],2) ^ 
multi(temp[2][1],3) ^ multi(temp[3][1],1);
		state[2][1] = multi(temp[0][1],1) ^ multi(temp[1][1],1) ^ 
multi(temp[2][1],2) ^ multi(temp[3][1],3);
		state[3][1] = multi(temp[0][1],3) ^ multi(temp[1][1],1) ^ 
multi(temp[2][1],1) ^ multi(temp[3][1],2);

		state[0][2] = multi(temp[0][2],2) ^ multi(temp[1][2],3) ^ 
multi(temp[2][2],1) ^ multi(temp[3][2],1);
		state[1][2] = multi(temp[0][2],1) ^ multi(temp[1][2],2) ^ 
multi(temp[2][2],3) ^ multi(temp[3][2],1);
		state[2][2] = multi(temp[0][2],1) ^ multi(temp[1][2],1) ^ 
multi(temp[2][2],2) ^ multi(temp[3][2],3);
		state[3][2] = multi(temp[0][2],3) ^ multi(temp[1][2],1) ^ 
multi(temp[2][2],1) ^ multi(temp[3][2],2);

		state[0][3] = multi(temp[0][3],2) ^ multi(temp[1][3],3) ^ 
multi(temp[2][3],1) ^ multi(temp[3][3],1);
		state[1][3] = multi(temp[0][3],1) ^ multi(temp[1][3],2) ^ 
multi(temp[2][3],3) ^ multi(temp[3][3],1);
		state[2][3] = multi(temp[0][3],1) ^ multi(temp[1][3],1) ^ 
multi(temp[2][3],2) ^ multi(temp[3][3],3);
		state[3][3] = multi(temp[0][3],3) ^ multi(temp[1][3],1) ^ 
multi(temp[2][3],1) ^ multi(temp[3][3],2);
		}
	else
		{
		state[0][0] = multi(temp[0][0],14) ^ multi(temp[1][0],11) ^ 
multi(temp[2][0],13) ^ multi(temp[3][0],9);
		state[1][0] = multi(temp[0][0],9) ^ multi(temp[1][0],14) ^ 
multi(temp[2][0],11) ^ multi(temp[3][0],13);
		state[2][0] = multi(temp[0][0],13) ^ multi(temp[1][0],9) ^ 
multi(temp[2][0],14) ^ multi(temp[3][0],11);
		state[3][0] = multi(temp[0][0],11) ^ multi(temp[1][0],13) ^ 
multi(temp[2][0],9) ^ multi(temp[3][0],14);

		state[0][1] = multi(temp[0][1],14) ^ multi(temp[1][1],11) ^ 
multi(temp[2][1],13) ^ multi(temp[3][1],9);
		state[1][1] = multi(temp[0][1],9) ^ multi(temp[1][1],14) ^ 
multi(temp[2][1],11) ^ multi(temp[3][1],13);
		state[2][1] = multi(temp[0][1],13) ^ multi(temp[1][1],9) ^ 
multi(temp[2][1],14) ^ multi(temp[3][1],11);
		state[3][1] = multi(temp[0][1],11) ^ multi(temp[1][1],13) ^ 
multi(temp[2][1],9) ^ multi(temp[3][1],14);

		state[0][2] = multi(temp[0][2],14) ^ multi(temp[1][2],11) ^ 
multi(temp[2][2],13) ^ multi(temp[3][2],9);
		state[1][2] = multi(temp[0][2],9) ^ multi(temp[1][2],14) ^ 
multi(temp[2][2],11) ^ multi(temp[3][2],13);
		state[2][2] = multi(temp[0][2],13) ^ multi(temp[1][2],9) ^ 
multi(temp[2][2],14) ^ multi(temp[3][2],11);
		state[3][2] = multi(temp[0][2],11) ^ multi(temp[1][2],13) ^ 
multi(temp[2][2],9) ^ multi(temp[3][2],14);

		state[0][3] = multi(temp[0][3],14) ^ multi(temp[1][3],11) ^ 
multi(temp[2][3],13) ^ multi(temp[3][3],9);
		state[1][3] = multi(temp[0][3],9) ^ multi(temp[1][3],14) ^ 
multi(temp[2][3],11) ^ multi(temp[3][3],13);
		state[2][3] = multi(temp[0][3],13) ^ multi(temp[1][3],9) ^ 
multi(temp[2][3],14) ^ multi(temp[3][3],11);
		state[3][3] = multi(temp[0][3],11) ^ multi(temp[1][3],13) ^ 
multi(temp[2][3],9) ^ multi(temp[3][3],14);
		}
	return 0;
	}

int add_round_key(unsigned char state[4][4], unsigned char 
round_key[4][4]) // penser a faire key selection et passer d'un tab 1n a 11 tab 44

	{
	int i,j;

	for(i = 0; i < 4; i++)
			{
			for(j = 0; j < 4; j++)
					{
					state[i][j] ^= round_key[i][j];
					}
			}

	return 0;
	}

int round(unsigned char state[4][4], unsigned char round_key[4][4], int 
round, unsigned char cmd)

	{
	if (cmd == 'c')
		{
		byte_sub(state, cmd);
		shift_row(state, cmd);
		if (round != 9) mix_column(state, cmd);
		add_round_key(state, 
round_key);
		}
	else
		{
		add_round_key(state, round_key);
		if (round != 9) mix_column(state, cmd);
		shift_row(state, cmd);
		byte_sub(state, cmd);
		}

	return 0;
	}

int rijndael(unsigned char cmd, unsigned char data[16], unsigned char 
cipher_key[16])

	{
	int i, j;
	unsigned char state[4][4];
	unsigned char expanded_key[11*16];
	unsigned char round_key[4][4];

	for(i = 0; i < 4; i++)
		{
		for(j = 0; j < 4; j++)
			{
			state[i][j] = data[i * 4 + j];
			}
		}

	expand_key(cipher_key, expanded_key);
	
	for(i = 0; i < 10; i++)
		{
		if (cmd == 'd') j = 9 - i;
		else j = i;

		select_key(expanded_key, round_key, j);
		round(state, round_key, j, cmd);
		}

	for(i = 0; i < 4; i++)
		{
		for(j = 0; j < 4; j++)
			{
			data[i * 4 + j] = state[i][j];
			}
		}

	return 0;
	}
int* taille_fichier(char *fic_quelq,int *table)//prgm qui donne le nombre de trames de  bits et le nombre d'octet de la dernière trame
{       //le tableau table contient en son indice 0 le nombre de trame de 128 bits et en son indice 1
        //le nombre d'octet de la deniere trame qui, elle ne fait pas toujours 16 octets
        void* p_lecture;
	FILE* desc_quelq;
     
	p_lecture = (void*)malloc(16); //tableau d'un paquet de 16 octets
	if(desc_quelq = fopen(fic_quelq,"rb"))
	{       while(( table[1] = fread(p_lecture,1,16,desc_quelq)) != 0) //lecture de 16 objets de 1 octet
		{       if(table[1]< 16 )
                        {      fclose(desc_quelq);
                               return table;
                        }                           
			table[0] ++;
		}
		fclose(desc_quelq);
                return table;
	}
	else
	{       printf("\nLe programme d'ouverture du fichier a rencontré un probleme et doit fermer.\nVeuillez le fermer et relancer  l'operation\n");
		free(p_lecture);
                return table;
	}
}
void gen_fic(char* nouv_fic,char* fic_quelq,int *table)//une procedure pour generrer le fichier qui
{                                                      //sera envoyé à l'uart.
        FILE *desc_nouv,*desc_quelq;
        void *p_lecture = NULL;
        p_lecture =(void*) malloc(16);
        desc_nouv = fopen(nouv_fic,"wb");
        desc_quelq = fopen(fic_quelq,"rb");
        
        if((desc_nouv!= NULL) && (desc_quelq !=NULL))
        {       fwrite(table,sizeof(int),2,desc_nouv);//ecriture de la taille du fichier à crypter
                fwrite(p_lecture,1,16-2*sizeof(int),desc_nouv);//la premiere trame vaut 128 bits
                while( (table[1] = fread(p_lecture,1,16,desc_quelq)) != 0)
                {       fwrite(p_lecture,1,16,desc_nouv);
                }
                fclose(desc_nouv);
                fclose(desc_quelq);
        }
        else
        {       printf("\nLe programme d'ouverture du fichier à crypter a rencontrer un problème et doit fermer.\n Veuillez le fermer et relancer la procedure.\n");
        }
}

void  lecture_fichier(char *file_send,char *file_received,char cmd,char *key)
{       //lit le fichier à envoyer à l'uart et crée un fichier pour stocker les trames qui 
        //viennent de l'uart , traitées ,envoie data, key et cmd à code_ip() pour crypter ou décrypter
        FILE *desc_send,*desc_received;
        char *p_lecture = NULL;
        p_lecture = (char*)malloc(16);//trame de 128 bits
        int nbr;
        desc_send = fopen(file_send,"rb");
        desc_received = fopen(file_received,"wb");
         if((desc_send!= NULL) && (desc_received !=NULL))//bonnes ouvertures de fichiers
         {      //fread(table,sizeof(int),2,desc_send);
                //printf("\nLes tailles recupérées sont de %d trames de 128 bits et de %d octets dasn la dernière trame",table[0],table[1]);
                //fseek(desc_send,SEEK_SET,16);//on se place à partir de la seconde trame
                //fwrite(table,sizeof(int),2,desc_received);//écriture dans le fichier reçu de l'uart de la taille du fichier de départ.
                //fwrite(p_lecture,1,16-2*sizeof(int),desc_received);//la premiere trame vaut 128 bits
                while((nbr = fread(p_lecture,1,16,desc_send)) != 0)
                        {rijndael(cmd,p_lecture,key);//cryptage
                        fwrite(p_lecture,1,16,desc_received);//écriture dans le fichier de reception
                        }
               fclose(desc_send);
               fclose(desc_received);
         }
         else
         {printf("\nLe programme d'ouverture du fichier à crypter a rencontrer un problème et doit fermer.\n Veuillez le fermer et relancer la procedure.\n");
         }

}

void gen_fic_quelq(char *nouv_fic,char *fic_quelq2)//géneration du fichier de départ à partir du fichier qui a un nombre entier de trames de 128 bits
{       int i;
        int tableau[3];//le tableau de lecture de la taille du fichier de depart
        tableau[0]=0;tableau[1]=0;//initialisation
        FILE *desc_nouv,*desc_quelq2;
        void *p_lecture =  NULL;
        
        p_lecture = (void*)malloc(16);
        desc_nouv = fopen(nouv_fic,"rb");
        desc_quelq2 = fopen(fic_quelq2,"wb");
        if((desc_nouv!= NULL) && (desc_quelq2 !=NULL))
        {       fread(tableau,sizeof(int),2,desc_nouv);//lecture de la taille du fichier
                fseek(desc_nouv,16,SEEK_SET);//saut des octets non significatifs
                for(i=0;i<tableau[0];i++)
                {       fread(p_lecture,1,16,desc_nouv);
                        fwrite(p_lecture,1,16,desc_quelq2);//lecture des blocs de 128 bits
                }
                fread(p_lecture,1,tableau[1],desc_nouv);
                fwrite(p_lecture,1,tableau[1],desc_quelq2);//ecriture de la partie significative de la dernire trame
                fclose(desc_quelq2);
                fclose(desc_nouv);
        }
        else
        {        free(p_lecture);
                 printf("\nLe programme d'ouverture du fichier à crypter a rencontrer un problème et doit fermer.\n Veuillez le fermer et relancer la procedure.\n");
        }
}

int main()
{       int table[3];
	int *lonfic2;
	char *fic_quelq,*nouv_fic,*fic_arrive,*fic_decrypte_recu,*dossier,key_temp [255],msg[]= "\nTapez 16 caractères correspondant à la clé de cryptage :\n";
        unsigned char key[17];
	int choix_menu,i,tours = 0;
        char cmd;
        printf("\n\tSoyez la bienvenue dans MINMOUCRYPT, le nouveau logiciel de cryptage\n\t qui apporte une confidentialité sans failles à vos données!!!\n\n");
        fic_quelq = (char*)malloc(60*sizeof(char));
        nouv_fic = (char*)malloc(60*sizeof(char));
        fic_arrive = (char*)malloc(60*sizeof(char));
        fic_decrypte_recu = (char*)malloc(60*sizeof(char));
        do{     printf("\n%s",msg);//saisie de la clef
                gets(key_temp);
                fflush(stdin);
                strcpy(msg,"Saisie incorrecte. Veuillez recommencer:\n");
        }while( strlen(key_temp)!= 16);
        strcpy(key,key_temp);//copie de la clef temporaire dans la definitive.
       do{
        table[0]=0; table[1]=0; //inintialisations de table        
        if(tours<1)
        {       printf("\n\tTapez le nom du fichier de départ:\t");
                fflush(stdin);
                scanf("%s",fic_quelq);
         
                printf("\n\tTapez le nom du fichier d'arrivée:\t");
                fflush(stdin);
                scanf("%s",fic_arrive);
        }
        strcpy(nouv_fic,"fic_gen.mm");//le fichier a transmettre qui a un nombre entier de trame de 128 bits
        strcpy(fic_decrypte_recu,"fichier_recu2.mm");//le fichier reçu de l'uart decrypté
                printf("---------------------------- MENU DES OPERATIONS--------------------------\n\n\n");
                printf("\t\t1- Calculer la taille du fichier à traiter\n");
                printf("\t\t2-Crypter le fichier de départ\n");
                printf("\t\t3-Décrypter le fichier de départ\n");
                printf("\t\t4-Changer de fichiers de départ et d'arrivée\n");
                printf("\t\t5-Crédits\n");
                printf("\t\t6-Quitter\n");
                printf("\n\tVeuillez taper votre choix:\t");
                fflush(stdin);
                scanf("%d",&choix_menu);
                lonfic2 =  taille_fichier(fic_quelq,table);
                switch(choix_menu)
                {       case 1: printf("\nLe nombre de paquet de 128 bits est de : \t%d \nle nombre d'octet de la derniere trame est de: \t%d\n",lonfic2[0],lonfic2[1]);    
                        break;
                        case 2: gen_fic(nouv_fic,fic_quelq,lonfic2);
                                lecture_fichier(nouv_fic,fic_arrive,'c',key);
                                printf("\nLe cryptage est terminé!!!!\n");
                        break;
                        case 3: lecture_fichier(fic_quelq,fic_decrypte_recu,'d',key);
                                gen_fic_quelq(fic_decrypte_recu,fic_arrive);
                                printf("\nLe décryptage est terminé!!!!\n");
                        break;
                        case 4:tours = -1;
                        break;
                        case 5: printf("\n\tMINMOUCRYPT, logiciel de cryptage/decryptage de données\n\tutilisant le nouveau puissant standard de cryptage AES.\n\t");
                                printf("Le cryptage et le decryptage utilisent l'algorithme de Rijndael.\n\tLa clé de cryptage a une longueur de 128 bits.");
                                printf("\n\tToutes modifications, utilisations publiques et autres actions \n\trepréhensibles sur ce logiciel sont interdites.\n\t");
                                printf("Et par conséquent feraient l'objet de poursuites judicaires si\n\telles sont constatées.\n");
                        break;
                        case 6: printf("\nMerci de nous faire confiance et d'avoir choisi MINMOUCRYPT");
                        break;
                        default:printf("\nCe choix ne convient pas. Veuillez saisir à nouveau votre choix\n\n");
                }
                tours++; 
       }while(choix_menu != 6);
        free(fic_arrive);
        free(fic_quelq);//liberation de memoire
        free(nouv_fic);
        free(fic_decrypte_recu);
        //free(fichier_crypte);
        return 0;
}

Conclusion :


Règle N°1: Ne jamais promettre....enfin vous devez savoir!
++

A voir également

Ajouter un commentaire

Commentaires

borz37
Messages postés
1
Date d'inscription
mercredi 29 mai 2013
Statut
Membre
Dernière intervention
1 juin 2013
-
Salut tout le monde est ce que quelqu'un peux m'aider svp??

Par ce que je cherche un hack rcon pour counter strike 1.6 mais je n'y arrive pas a trouvé,
et aussi je n'y comprend rien au code source est ce que quelqu'un peux m'envoyer un message privé SVP.

Merci
cs_mitch53
Messages postés
3
Date d'inscription
lundi 5 mai 2003
Statut
Membre
Dernière intervention
7 novembre 2007
-
Il est faut ce code...
il ne respecte pas la norme fips pour aes...

Y a deja une erreur dans la première fonction qui produit rcon....
Ce ne sont pas des puissances de 2.
les valeurs de rcon doivent etre:
0x01
0x02
0x04
0x08
0x10
0x20
0x40
0x80
0x1b
0x36
cs_zeinab
Messages postés
1
Date d'inscription
mardi 1 août 2006
Statut
Membre
Dernière intervention
22 août 2006
-
bonjour, je n'arrive pa à exécuter ce code source sur le visual c++. Je lé exécuter sur le turbo C mai le decryptage ne fonctionne pa
PseudoSeeker
Messages postés
1
Date d'inscription
mardi 15 juin 2004
Statut
Membre
Dernière intervention
8 juin 2005
-
Bravo pour ce code, ca marche nickel, sauf le pb de cast deja evoqué, mais c un detail.
Par contre, en m'amusant avec, j'ai regardé les credits. Ce code ne doit pas etre reutilisé? Je ne comprends pas bien le principe du coup, surtout quand on fournit les sources.
Bref, du coup je suis bien embeté parce que j'etais parti pour m'en servir dans un prog a titre professionnel, et je ne sais plus si je suis dans mon bon droit.
nawsa
Messages postés
3
Date d'inscription
dimanche 24 avril 2005
Statut
Membre
Dernière intervention
18 mai 2005
-
Salut tout le monde, j'ai encore une petite question à poser, en utilisant cette source j'essayais de crypter et de décrypter sur le même ordinateur, en pensant que le fichier de départ devait contenir le message originale,et que le fichier d'arrivé contiendrait tour à tour le fichier crypté puis le décrypté.
Mais en lisant mieux la source j'ai cru comprendre que l'on devait envoyer notre message à une autre machine, alors comment dans ce cas spécifie-t-on l'adresse ip.

excusez mon igniorance et répondez moi s'il vous plait.
merci d'avance.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.