// event. click on 'Décoder' boutton du tabPage2 private void decoderBtn_Click(object sender, EventArgs e) { try { // remise à zéro de la barre de chargement progressBar2.Value = 0; // vidage de la zone/textBox du texte caché txtCacherTab2.Text = ""; // 1 - lecture du fichier audio en bytes if (wavFileLabelTab2.Text == "Aucun fichier séléctionné.") { MessageBox.Show("Aucun fichier audio séléctionné !", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } byte[] fileBytes = File.ReadAllBytes(wavFileLabelTab2.Text); // 2 - si clé stégo non saisi if (cleStegoTab2.Text == "") { MessageBox.Show("Aucune clé stégo saisie !", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 3 - si mot de passe de décryptage AES non saisi if (mdpTab2.Text == "") { MessageBox.Show("Aucun mot de passe (AES) saisi !", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 3 - Toutes les vérifications ont été faites, Let's decrypt this ! // on commence le calcul du temp d'éxecution Stopwatch sw = new Stopwatch(); sw.Start(); // conversion du fichier audio en block de 2/4 bits string[] fileBitBlocks = ToolsAndFunctions.bytesToBlocks(fileBytes, nombreDeBit); // décryptage de la clé stégo string cleStegoString = Crypt.DecryptStringAES(cleStegoTab2.Text, mdpTab2.Text); // on récupère le hash du fichier audio et les positions des blocks string[] positions = cleStegoString.Split('|'); //MessageBox.Show(cleStegoString + "," + fileBitBlocks[Convert.ToInt32(positions[0])], ""); // vérification du Hash du fichier audio avec celui contenu dans la clé string fileHash = positions[0]; if (fileHash != ToolsAndFunctions.GetFileHash(fileBytes)) // si les 2 hash ne sont pas identiques { MessageBox.Show("Fichier audio erroné !", "Stop", MessageBoxButtons.OK, MessageBoxIcon.Stop); return; } // Recherche dans les blocks du fichier audio string texteCachee = ""; // on parcours toutes les positions pour reconstituer le texte caché for (int i = 1; i < positions.Length - 1; i += (8 / nombreDeBit)) // de 1 => première position contient le hash, 8(bits) / 4(bits par block) = 2 , -1 du dernier '|' { string Blocks = ""; // contiendra 2 bloc si codage sur (4bit) ou 4 bloc si codage sur (2bit) for (int j = 0; j < (8 / nombreDeBit); j++) { Blocks += fileBitBlocks[Convert.ToInt32(positions[i + j])]; } //MessageBox.Show(positions.Length.ToString() + "," + i.ToString() + "," + texteCachee); texteCachee += ToolsAndFunctions.BlocksToString(Blocks); } // on arrête le calcul du temp d'éxecution + on l'affiche sw.Stop(); execTimeTab2.Text = sw.ElapsedMilliseconds.ToString() + " ms"; // affichage du texte caché txtCacherTab2.Text = texteCachee; // chargement complet de la barre de chargement progressBar2.Value = 100; } // fin try catch (Exception ex) { MessageBox.Show("[Erreur de décodage : " + ex.Message + "]\nIl se peut que le mot de passe ou la clé stégo soit incorrecte !", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }
// event. click on 'Coder' boutton du tabPage1 private void coderBtn_Click(object sender, EventArgs e) { try { // remise à zéro de la barre de chargement progressBar1.Value = 0; // Désactivation des bouttons 'Relire..' et 'Décodage Rapide..' + save replayAudioBtn.Enabled = decodageRapideBtn.Enabled = saveCleStegoBtn.Enabled = false; // 1 - lecture du fichier audio en bytes if (wavFileLabelTab1.Text == "Aucun fichier séléctionné.") { MessageBox.Show("Aucun fichier audio séléctionné !", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } byte[] fileBytes = File.ReadAllBytes(wavFileLabelTab1.Text); // 2 - Conversion du texte a cacher en bytes if (txtAcacherTab1.Text == "") { MessageBox.Show("Aucun texte à cacher !", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } byte[] textBytes = System.Text.Encoding.ASCII.GetBytes(txtAcacherTab1.Text); // si mot de passe de cryptage AES non saisi if (mdpTab1.Text == "") { MessageBox.Show("Aucun mot de passe (AES) saisi !", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } // 3 - Toutes les vérifications ont été faites, Let's Go ! // on commence le calcul du temp d'éxecution Stopwatch sw = new Stopwatch(); sw.Start(); // conversion du fichier audio en block de 2/4 bits string[] fileBitBlocks = ToolsAndFunctions.bytesToBlocks(fileBytes, nombreDeBit); // conversion du text à cacher en block de 2/4 bits string[] textBitBlocks = ToolsAndFunctions.bytesToBlocks(textBytes, nombreDeBit); // Recherche Locale int[] positions = new int[textBytes.Length * (8 / nombreDeBit)]; // 8(bits) / 4 (bits par block) = 2 (positions pour chaque 8bit) if (methode == 1) // si methode Fitness et voisinage { int[] fitness = new int[textBitBlocks.Length]; // pr chaque bloc une fitness int[] randomPos = new int[textBitBlocks.Length]; // pr chaque bloc une position aléatoire Random rnd = new Random(); // Etape 1 : Position aléatoire // on parcours les blocks du texte à cacher for (int i = 0; i < textBitBlocks.Length; i++) { // pr chaque bloc de texte on génère une position aléatoire dans les blocs audio randomPos[i] = rnd.Next(0, fileBitBlocks.Length - 1); // -1 car le tableau commence de 0 // on calcule la fitness du bloc fitness[i] = ToolsAndFunctions.fitness(textBitBlocks[i], fileBitBlocks[randomPos[i]]); //MessageBox.Show(fitness[i].ToString()); } // Etape 2 : Vérification de la fitness de chaque bloc, puis recherche au voisinage si fitness != 0 // on parcours les blocks du texte à cacher for (int i = 0; i < textBitBlocks.Length; i++) { if (fitness[i] != 0) { // recherche au voisinage de l'ancienne randomPos[i] int k = randomPos[i]; // initialisation avec la randomPos[i] // 1 - recherche au voisinage droit (1er bloc a droite) for (int j = randomPos[i] + 1; j < fileBitBlocks.Length; j++) // depuis randomPos[i] + 1 { // on recalcule la fitness du bloc fitness[i] = ToolsAndFunctions.fitness(textBitBlocks[i], fileBitBlocks[j]); //MessageBox.Show(i.ToString() + " - voisinage droite - " + j.ToString()); // si la fitness != 0 tj if (fitness[i] != 0) { // 2 - recherche au voisinage gauche (1er bloc a gauche), içi on vérifie juste 1 seul bloc, pr repasser la main a la 1ere boucle for if (k > 0) // si on peu décrémenter k (=> y'a encore du voisinage gauche) { k--; // on recalcule la fitness du bloc fitness[i] = ToolsAndFunctions.fitness(textBitBlocks[i], fileBitBlocks[k]); //MessageBox.Show(i.ToString() + " - voisinage gauche - " + k.ToString()); // si fitness == 0, c'est bon, on sauvegarde la position et on sort de la boucle (1ere boucle for) if (fitness[i] == 0) { // ça veux dire qu'on a trouvé le bloc au voisinage gauche positions[i] = k; break; } } } else // si nn => fitness == 0, c'est bon, on sauvegarde la position et on sort de la boucle (1ere boucle for) { // ça veux dire qu'on a trouvé le bloc au voisinage droit positions[i] = j; break; } } // si jamais la boucle du voisinage à droite prend fin alors que la fitness != 0, on n'ai pas sur alors que la boucle du voisinage à gauche a fini aussi ! if (fitness[i] != 0) { // 3 - Finition de la recherche au voisinage gauche for (int f = k; f >= 0; f--) { // on recalcule la fitness du bloc fitness[i] = ToolsAndFunctions.fitness(textBitBlocks[i], fileBitBlocks[f]); //MessageBox.Show(i.ToString() + " - voisinage gauche (boucle) - " + f.ToString()); // si fitness == 0, c'est bon, on sauvegarde la position et on sort de la boucle if (fitness[i] == 0) { positions[i] = f; break; } } // si jamais apres tt ça la fitness != 0 tj, alors qu'on a parcouru toute la boucle, ça veux dire que le bloc est introuvable if (fitness[i] != 0) { throw new Exception("Le bloc : '" + textBitBlocks[i] + "' est introuvable dans les blocs du fichier audio !"); } } // fin if } else // si fitness == 0, autrement dit, si les blocs (texte et audio) se ressemble, on passe au prochain bloc { positions[i] = randomPos[i]; } } // fin for => Etape 2 } else // si nn (les 2 autres méthodes) { int lastPosition; Random rnd = new Random(); if (methode == 2) // si recherche en boucle { lastPosition = 0; // le nom de la variable ne reflète pas le role qu'elle joue , je sais.. } else // si nn (recherche aléatoire, car si methode == 3 on ne rentrera jamais içi), on genère un nombre aléatoire { lastPosition = rnd.Next(0, fileBitBlocks.Length - 2); // - 2 pour avoir au moin un block suivant (car le tableau de block commence de 0 et fini en fileBitBlocks.Length - 1) } // chargement à 30% de la barre de chargement //progressBar1.Value = 30; // ça ne s'applique pas, forcément car, on entre apres dans des boucles => on bloque la GUI (redessinage..) // on parcours les blocks du texte à cacher for (int i = 0; i < textBitBlocks.Length; i++) { bool positionOk = false; while (!positionOk) { // on parcours les blocks du fichier audio for (int j = lastPosition; j < fileBitBlocks.Length; j++) { //MessageBox.Show(textBitBlocks[i] + "-" + fileBitBlocks[j] + "-" + i.ToString() + "-" + j.ToString(), ""); // si on trouve un block de texte dans le fichier audio if (textBitBlocks[i] == fileBitBlocks[j]) { // on sauvegarde la position dans la clé stégo/tableau de positions positions[i] = j; //lastPosition = ++j; // ou j + 1 positionOk = true; break; // on sort de la boucle sur les blocks du fichier audio pour passer au prochain block de texte } } // fin 2eme for if (methode == 3) // si méthode de recherche aléatoire { if (!positionOk) // si on n'a pas trouvé la position du block avec la valeur aléatoire { // on vérifie si le block existe déja dans le fichier audio et on retourne sa position, si nn la fonction retourne -1 lastPosition = ToolsAndFunctions.isBlockExists(textBitBlocks[i], fileBitBlocks); if (lastPosition == -1) { throw new Exception("Le bloc : '" + textBitBlocks[i] + "' est introuvable dans les blocs du fichier audio !"); } // si nn si position trouvé la boucle va continuer son travail (meme si on l'a aider pr avoir la position + c'est plus rapide comme ça meme si ce n'est plus completement aléatoire) } else { lastPosition = rnd.Next(0, fileBitBlocks.Length - 1); // on regénère un nombre aléatoire } } else // si nn, methode en boucle { if (!positionOk) // si jamais on ne trouve pas le bloc apres avoir parcouru tout le fichier, positionOk sera = à false (c peu probable, mais si ça arrive, ça provequera une boucle infini, 'mieux vaut prévenir que guérir !') { throw new Exception("Le bloc : '" + textBitBlocks[i] + "' est introuvable dans les blocs du fichier audio !"); } else { break; // on sort de la boucle while, pour passer au bloc suivant } } } // fin while } // fin 1er for } // fin else // traitement de la clé stégo => Ajout du Hash du fichier audio string cleStegoString = ToolsAndFunctions.GetFileHash(fileBytes) + "|"; for (int i = 0; i < positions.Length; i++) // Ajout des positions des blocks { cleStegoString += positions[i].ToString() + "|"; // conversion en chaine de caractère } //MessageBox.Show(cleStegoString, "Clé stégo en clair", MessageBoxButtons.OK, MessageBoxIcon.Information); // cryptage de la clé stégo + affichage cleStegoTab1.Text = Crypt.EncryptStringAES(cleStegoString, mdpTab1.Text); // on arrête le calcul du temp d'éxecution + on l'affiche sw.Stop(); execTimeTab1.Text = sw.ElapsedMilliseconds.ToString() + " ms"; // chargement complet de la barre de chargement progressBar1.Value = 100; // Activation des bouttons 'Relire..' et 'Décodage Rapide..' + save replayAudioBtn.Enabled = decodageRapideBtn.Enabled = saveCleStegoBtn.Enabled = true; } // fin try catch (Exception ex) { MessageBox.Show(ex.Message, "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Warning); } }