mirror of
https://github.com/ArthurDanjou/ArtStudies.git
synced 2026-03-16 01:12:03 +01:00
Add new images and update README for Cybersecurity section
- Added `image_secrete.bmp` and `image_test_8bits.bmp` to the Cybersecurity directory. - Updated README.md to include a new section for Cybersecurity, highlighting data security and analysis.
This commit is contained in:
624
M2/Cybersecurity/LSB_GSB.ipynb
Normal file
624
M2/Cybersecurity/LSB_GSB.ipynb
Normal file
@@ -0,0 +1,624 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {
|
||||
"id": "siM8xBq5kDja"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from PIL import Image\n",
|
||||
"\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import numpy as np\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {
|
||||
"id": "QeDEw-sukFj9"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def texte_vers_binaire(texte):\n",
|
||||
" \"\"\"Convertit un string en une chaîne de caractères binaires (8 bits par caractère).\"\"\"\n",
|
||||
" return \"\".join(format(ord(c), \"08b\") for c in texte)\n",
|
||||
"\n",
|
||||
"def binaire_vers_texte(chaine_binaire):\n",
|
||||
" \"\"\"Convertit une chaîne de caractères binaires en string.\"\"\"\n",
|
||||
" octets = [chaine_binaire[i:i+8] for i in range(0, len(chaine_binaire), 8)]\n",
|
||||
" return \"\".join(chr(int(octet, 2)) for octet in octets if len(octet) == 8)\n",
|
||||
"\n",
|
||||
"DELIMITEUR = \"#####\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"id": "ULmRSCIExZ2j"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def cacher_message(chemin_image_entree, message_secret, chemin_image_sortie):\n",
|
||||
" # On ouvre l'image et on s'assure qu'elle est en 8-bits (Niveaux de gris = mode 'L')\n",
|
||||
" img = Image.open(chemin_image_entree).convert(\"L\")\n",
|
||||
" pixels = np.array(img)\n",
|
||||
"\n",
|
||||
" # On ajoute le délimiteur à la fin du message et on convertit tout en binaire\n",
|
||||
" message_complet = message_secret + DELIMITEUR\n",
|
||||
" message_binaire = texte_vers_binaire(message_complet)\n",
|
||||
"\n",
|
||||
" # On aplatit le tableau de pixels en 1D pour faciliter le parcours\n",
|
||||
" pixels_plats = pixels.flatten()\n",
|
||||
"\n",
|
||||
" # Vérification de la capacité de l'image\n",
|
||||
" if len(message_binaire) > len(pixels_plats):\n",
|
||||
" raise ValueError(\"Message is too long for the image.\")\n",
|
||||
"\n",
|
||||
" # Remplacement du bit de poids faible (LSB)\n",
|
||||
" for i in range(len(message_binaire)):\n",
|
||||
" bit_a_cacher = int(message_binaire[i])\n",
|
||||
" # L'opération bit à bit '& 254' force le dernier bit à 0, puis on fait un 'OU' avec notre bit\n",
|
||||
" pixels_plats[i] = (pixels_plats[i] & 254) | bit_a_cacher\n",
|
||||
"\n",
|
||||
" # On redonne à l'image sa forme originale et on sauvegarde\n",
|
||||
" pixels_modifies = pixels_plats.reshape(pixels.shape)\n",
|
||||
" img_modifiee = Image.fromarray(pixels_modifies, mode=\"L\")\n",
|
||||
" img_modifiee.save(chemin_image_sortie, format=\"BMP\")\n",
|
||||
" print(f\"Message succesfully hidden in : {chemin_image_sortie}\")\n",
|
||||
"\n",
|
||||
"# --- 3. FONCTION POUR EXTRAIRE LE MESSAGE (DÉCODAGE LSB) ---\n",
|
||||
"\n",
|
||||
"def extraire_message(chemin_image):\n",
|
||||
" # On ouvre l'image modifiée\n",
|
||||
" img = Image.open(chemin_image).convert(\"L\")\n",
|
||||
" pixels_plats = np.array(img).flatten()\n",
|
||||
"\n",
|
||||
" bits_extraits = []\n",
|
||||
"\n",
|
||||
" # On récupère le dernier bit de chaque pixel\n",
|
||||
" for pixel in pixels_plats:\n",
|
||||
" bits_extraits.append(str(pixel & 1))\n",
|
||||
"\n",
|
||||
" chaine_binaire_complete = \"\".join(bits_extraits)\n",
|
||||
"\n",
|
||||
" # On lit le binaire par paquets de 8 bits (1 octet = 1 caractère)\n",
|
||||
" message_decode = \"\"\n",
|
||||
" for i in range(0, len(chaine_binaire_complete), 8):\n",
|
||||
" octet = chaine_binaire_complete[i:i+8]\n",
|
||||
" if len(octet) < 8:\n",
|
||||
" break\n",
|
||||
" caractere = chr(int(octet, 2))\n",
|
||||
" message_decode += caractere\n",
|
||||
"\n",
|
||||
" # On s'arrête si on détecte le délimiteur\n",
|
||||
" if message_decode.endswith(DELIMITEUR):\n",
|
||||
" # On retourne le message sans le délimiteur\n",
|
||||
" return message_decode[:-len(DELIMITEUR)]\n",
|
||||
"\n",
|
||||
" return \"No hidden message found (or delimiter not found).\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {
|
||||
"id": "g_e4U9O4lIOb"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"nom_fichier_sortie = \"image_secrete.bmp\"\n",
|
||||
"mon_message = \"Decode this!\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "oLpz4m1vk-zF",
|
||||
"outputId": "1cdb06cb-9c4e-4131-b7a3-d76be6930c11"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Image 'image_test_8bits.bmp' created successfully!\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 1. On définit la taille de l'image (par exemple 256 pixels par 256 pixels)\n",
|
||||
"largeur, hauteur = 256, 256\n",
|
||||
"\n",
|
||||
"# 2. On crée un tableau rempli de zéros (qui correspondra à du noir)\n",
|
||||
"pixels = np.zeros((hauteur, largeur), dtype=np.uint8)\n",
|
||||
"\n",
|
||||
"# 3. On crée un dégradé horizontal\n",
|
||||
"# Chaque colonne prend la valeur de son index (de 0 à 255)\n",
|
||||
"for x in range(largeur):\n",
|
||||
" pixels[:, x] = x\n",
|
||||
"\n",
|
||||
"# 4. On convertit le tableau NumPy en image PIL (mode 'L' = 8 bits niveaux de gris)\n",
|
||||
"image_test = Image.fromarray(pixels, mode=\"L\")\n",
|
||||
"\n",
|
||||
"# 5. On sauvegarde le fichier au format BMP\n",
|
||||
"nom_fichier = \"image_test_8bits.bmp\"\n",
|
||||
"image_test.save(nom_fichier, format=\"BMP\")\n",
|
||||
"\n",
|
||||
"print(f\"Image '{nom_fichier}' created successfully!\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 602
|
||||
},
|
||||
"id": "s9NtmhpUkU8T",
|
||||
"outputId": "699b8055-5e19-4fde-94fc-44464672a291"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAEAAQABAREA/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEBAAA/APAkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSv/2Q==",
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAAAAAB5Gfe6AAACuUlEQVR4AWJkYBzZgIlhhIPRABjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoCgBshCcABgCdkAL/fkEcHQAAAABJRU5ErkJggg==",
|
||||
"text/plain": [
|
||||
"<PIL.BmpImagePlugin.BmpImageFile image mode=L size=256x256>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Message succesfully hidden in : image_secrete.bmp\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAEAAQABAREA/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEBAAA/APAkqwlWEqylTpVhKsJVhKsJVhKspU6VYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK//2Q==",
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAAAAAB5Gfe6AAAEwElEQVR4AWJkYGRkYAJjpv9MjCDA9J+JgZmBkZHpPzMDE5hGkWdg/s/EwMTAxAiSA+ll+g8WAakHm8DEwAjSD1HHyAimmUFiEHNx8UFWDwBmYmBgYITg/yCagYHhPyMD438w/Z8BQqPIM4LkQXpAcmAaIsLwH0SD9DGA9YN4IBPB9H+QGMRcXHyGgQGgABgYmweJraMBMEgiYsCcMRoAAxb0g8Ti0QAYJBExYM4YDYABC/pBYvFoAAySiBgwZ4wGwIAF/SCxeDQABklEDJgzRgNgwIJ+kFg8GgCDJCIGzBmjATBgQT9ILB4NgEESEQPmjNEAGLCgHyQWjwbAIImIAXPGaAAMWNAPEotHA2CQRMSAOWM0AAYs6AeJxaMBMEgiYsCcMRoAAxb0g8Ti0QAYJBExYM4YDYABC/pBYvFoAAySiBgwZ4wGwIAF/SCxeDQABklEDJgzRgNgwIJ+kFg8GgCDJCIGzBmjATBgQT9ILB4NgEESEQPmjNEAGLCgHyQWjwbAIImIAXPGaAAMWNAPEotHA2CQRMSAOWM0AAYs6AeJxaMBMEgiYsCcMRoAAxb0g8Ti0QAYJBExYM4YDYABC/pBYvFoAAySiBgwZ4wGwIAF/SCxeDQABklEDJgzRgNgwIJ+kFg8GgCDJCIGzBmjATBgQT9ILB4NgEESEQPmjNEAGLCgHyQWjwbAIImIAXPGaAAMWNAPEotHA2CQRMSAOWM0AAYs6AeJxaMBMEgiYsCcMRoAAxb0g8Ti0QAYJBExYM4YDYABC/pBYvFoAAySiBgwZ4wGwIAF/SCxeDQABklEDJgzRgNgwIJ+kFg8GgCDJCIGzBmjATBgQT9ILB4NgEESEQPmjNEAGLCgHyQWjwbAIImIAXPGaAAMWNAPEotHA2CQRMSAOWM0AAYs6AeJxaMBMEgiYsCcMRoAAxb0g8Ti0QAYJBExYM4YDYABC/pBYvFoAAySiBgwZ4wGwIAF/SCxeDQABklEDJgzRgNgwIJ+kFg8GgCDJCIGzBmjATBgQT9ILB4NgEESEQPmjNEAGLCgHyQWjwbAIImIAXPGaAAMWNAPEotHA2CQRMSAOWM0AAYs6AeJxaMBMEgiYsCcMRoAAxb0g8Ti0QAYJBExYM4YDYABC/pBYvFoAAySiBgwZ4wGwIAF/SCxeDQABklEDJgzRgNgwIJ+kFg8GgCDJCIGzBmjATBgQT9ILB4NgEESEQPmjNEAGLCgHyQWjwbAIImIAXPGaAAMWNAPEotHA2CQRMSAOWM0AAYs6AeJxaMBMEgiYsCcMRoAAxb0g8Ti0QAYJBExYM4YDYABC/pBYvFoAAySiBgwZ4wGwIAF/SCxeDQABklEDJgzRgNgwIJ+kFg8GgCDJCIGzBmjATBgQT9ILB4NgEESEQPmjNEAGLCgHyQWjwbAIImIAXPGaAAMWNAPEotHA2CQRMSAOWM0AAYs6AeJxaMBMEgiYsCcMRoAAxb0g8Ti0QAYJBExYM4YDYABC/pBYvFoAAySiBgwZ4wGwIAF/SCxeDQABklEDJgzRgNgwIJ+kFg8GgCDJCIGzBmjATBgQT9ILB4NgEESEQPmjNEAGLCgHyQWjwbAIImIAXPGaAAMWNAPEosBG/EBAACB7C4KJpffiQAAAABJRU5ErkJggg==",
|
||||
"text/plain": [
|
||||
"<PIL.BmpImagePlugin.BmpImageFile image mode=L size=256x256>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Message : Decode this!\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"display(Image.open(nom_fichier))\n",
|
||||
"# 2. Cacher le message\n",
|
||||
"cacher_message(nom_fichier, mon_message, nom_fichier_sortie)\n",
|
||||
"\n",
|
||||
"#display the image\n",
|
||||
"display(Image.open(nom_fichier_sortie))\n",
|
||||
"\n",
|
||||
"# 3. Extraire le message\n",
|
||||
"message_trouve = extraire_message(nom_fichier_sortie)\n",
|
||||
"print(f\"Message : {message_trouve}\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {
|
||||
"id": "HUvxyPw-knd9"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"image_sortie = Image.open(nom_fichier_sortie)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 562
|
||||
},
|
||||
"id": "YW7UFBzMn7I7",
|
||||
"outputId": "ddfdd830-f1ff-465a-d2e5-e45767510400"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "ValueError",
|
||||
"evalue": "Message is too long for the image.",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[31m---------------------------------------------------------------------------\u001b[39m",
|
||||
"\u001b[31mValueError\u001b[39m Traceback (most recent call last)",
|
||||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 8\u001b[39m\n\u001b[32m 5\u001b[39m image_stego = \u001b[33m\"\u001b[39m\u001b[33mimage_secrete.bmp\u001b[39m\u001b[33m\"\u001b[39m\n\u001b[32m 7\u001b[39m \u001b[38;5;66;03m# On cache ce long message dans notre image de test\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m8\u001b[39m \u001b[43mcacher_message\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimage_originale\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlong_message\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mimage_stego\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 10\u001b[39m \u001b[38;5;66;03m# 2. Fonction pour extraire tous les LSB d'une image\u001b[39;00m\n\u001b[32m 11\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mextraire_tous_les_lsb\u001b[39m(chemin_image):\n",
|
||||
"\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[3]\u001b[39m\u001b[32m, line 15\u001b[39m, in \u001b[36mcacher_message\u001b[39m\u001b[34m(chemin_image_entree, message_secret, chemin_image_sortie)\u001b[39m\n\u001b[32m 13\u001b[39m \u001b[38;5;66;03m# Vérification de la capacité de l'image\u001b[39;00m\n\u001b[32m 14\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(message_binaire) > \u001b[38;5;28mlen\u001b[39m(pixels_plats):\n\u001b[32m---> \u001b[39m\u001b[32m15\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33m\"\u001b[39m\u001b[33mMessage is too long for the image.\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 17\u001b[39m \u001b[38;5;66;03m# Remplacement du bit de poids faible (LSB)\u001b[39;00m\n\u001b[32m 18\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(\u001b[38;5;28mlen\u001b[39m(message_binaire)):\n",
|
||||
"\u001b[31mValueError\u001b[39m: Message is too long for the image."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# 1. Préparation d'un LONG message pour que l'effet stégo soit visible\n",
|
||||
"# On crée un faux message assez long pour remplir une bonne partie de l'image (256x256 = 65536 pixels)\n",
|
||||
"long_message = \"Check if we can decode everything, like long messages\" * 200\n",
|
||||
"image_originale = \"image_test_8bits.bmp\"\n",
|
||||
"image_stego = \"image_secrete.bmp\"\n",
|
||||
"\n",
|
||||
"# On cache ce long message dans notre image de test\n",
|
||||
"cacher_message(image_originale, long_message, image_stego)\n",
|
||||
"\n",
|
||||
"# 2. Fonction pour extraire tous les LSB d'une image\n",
|
||||
"def extraire_tous_les_lsb(chemin_image):\n",
|
||||
" img = Image.open(chemin_image).convert(\"L\")\n",
|
||||
" pixels = np.array(img).flatten()\n",
|
||||
" # On récupère uniquement le dernier bit avec l'opérateur '& 1'\n",
|
||||
" return pixels & 1\n",
|
||||
"\n",
|
||||
"# On extrait les LSB des deux images\n",
|
||||
"lsb_orig = extraire_tous_les_lsb(image_originale)\n",
|
||||
"lsb_stego = extraire_tous_les_lsb(image_stego)\n",
|
||||
"\n",
|
||||
"# 3. Création des graphiques avec Matplotlib\n",
|
||||
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) # 1 ligne, 2 colonnes\n",
|
||||
"\n",
|
||||
"# --- Graphique de gauche : Image Stego ---\n",
|
||||
"ax1.hist(lsb_stego, bins=[-0.5, 0.5, 1.5], edgecolor=\"black\", alpha=0.7)\n",
|
||||
"ax1.set_title(\"Histogramme des LSB - Image Stego\")\n",
|
||||
"ax1.set_xticks([0, 1])\n",
|
||||
"ax1.set_xticklabels([\"LSB=0\", \"LSB=1\"])\n",
|
||||
"ax1.set_ylabel(\"Nombre d'occurrences\")\n",
|
||||
"\n",
|
||||
"# --- Graphique de droite : Image Originale ---\n",
|
||||
"ax2.hist(lsb_orig, bins=[-0.5, 0.5, 1.5], edgecolor=\"black\", alpha=0.7)\n",
|
||||
"ax2.set_title(\"Histogramme des LSB - Image Originale\")\n",
|
||||
"ax2.set_xticks([0, 1])\n",
|
||||
"ax2.set_xticklabels([\"LSB=0\", \"LSB=1\"])\n",
|
||||
"ax2.set_ylabel(\"Nombre d'occurrences\")\n",
|
||||
"\n",
|
||||
"# Affichage du résultat\n",
|
||||
"plt.tight_layout()\n",
|
||||
"plt.show()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "0ZLEleEjmyyZ"
|
||||
},
|
||||
"source": [
|
||||
"GSB"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "Y4uXeBJ_m7D7"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def cacher_messageGSB(chemin_image_entree, message_secret, chemin_image_sortie):\n",
|
||||
" # On ouvre l'image et on s'assure qu'elle est en 8-bits (Niveaux de gris = mode 'L')\n",
|
||||
" img = Image.open(chemin_image_entree).convert(\"L\")\n",
|
||||
" pixels = np.array(img)\n",
|
||||
"\n",
|
||||
" # On ajoute le délimiteur à la fin du message et on convertit tout en binaire\n",
|
||||
" message_complet = message_secret + DELIMITEUR\n",
|
||||
" message_binaire = texte_vers_binaire(message_complet)\n",
|
||||
"\n",
|
||||
" # On aplatit le tableau de pixels en 1D pour faciliter le parcours\n",
|
||||
" pixels_plats = pixels.flatten()\n",
|
||||
"\n",
|
||||
" # Vérification de la capacité de l'image\n",
|
||||
" if len(message_binaire) > len(pixels_plats):\n",
|
||||
" raise ValueError(\"The image is too small.\")\n",
|
||||
"\n",
|
||||
" # Remplacement du bit de poids faible (LSB)\n",
|
||||
" for i in range(len(message_binaire)):\n",
|
||||
" bit_a_cacher = int(message_binaire[i])\n",
|
||||
" # bit_a_cacher << 7 décale le bit de 7 crans vers la gauche\n",
|
||||
" pixels_plats[i] = (pixels_plats[i] & 127) | (bit_a_cacher << 7)\n",
|
||||
"\n",
|
||||
" # On redonne à l'image sa forme originale et on sauvegarde\n",
|
||||
" pixels_modifies = pixels_plats.reshape(pixels.shape)\n",
|
||||
" img_modifiee = Image.fromarray(pixels_modifies, mode=\"L\")\n",
|
||||
" img_modifiee.save(chemin_image_sortie, format=\"BMP\")\n",
|
||||
" print(f\"Message well hidden within : {chemin_image_sortie}\")\n",
|
||||
"\n",
|
||||
"# --- 3. FONCTION POUR EXTRAIRE LE MESSAGE (DÉCODAGE LSB) ---\n",
|
||||
"\n",
|
||||
"def extraire_messageGSB(chemin_image):\n",
|
||||
" # On ouvre l'image modifiée\n",
|
||||
" img = Image.open(chemin_image).convert(\"L\")\n",
|
||||
" pixels_plats = np.array(img).flatten()\n",
|
||||
"\n",
|
||||
" bits_extraits = []\n",
|
||||
"\n",
|
||||
" # On récupère le dernier bit de chaque pixel\n",
|
||||
" for pixel in pixels_plats:\n",
|
||||
" # On isole le bit de poids fort, puis on le ramène tout à droite\n",
|
||||
" bits_extraits.append(str((pixel & 128) >> 7))\n",
|
||||
"\n",
|
||||
" chaine_binaire_complete = \"\".join(bits_extraits)\n",
|
||||
"\n",
|
||||
" # On lit le binaire par paquets de 8 bits (1 octet = 1 caractère)\n",
|
||||
" message_decode = \"\"\n",
|
||||
" for i in range(0, len(chaine_binaire_complete), 8):\n",
|
||||
" octet = chaine_binaire_complete[i:i+8]\n",
|
||||
" if len(octet) < 8:\n",
|
||||
" break\n",
|
||||
" caractere = chr(int(octet, 2))\n",
|
||||
" message_decode += caractere\n",
|
||||
"\n",
|
||||
" # On s'arrête si on détecte le délimiteur\n",
|
||||
" if message_decode.endswith(DELIMITEUR):\n",
|
||||
" # On retourne le message sans le délimiteur\n",
|
||||
" return message_decode[:-len(DELIMITEUR)]\n",
|
||||
"\n",
|
||||
" return \"No hidden message found (or delimiter not found).\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
"height": 602
|
||||
},
|
||||
"id": "74Rinzm2nM7x",
|
||||
"outputId": "5a12f02b-6db5-431b-f872-b28e57dd12fe"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAEAAQABAREA/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEBAAA/APAkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSv/2Q==",
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAAAAAB5Gfe6AAACuUlEQVR4AWJkYBzZgIlhhIPRABjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoChjhCWA0BYymgNEsMMLBaAoY4QlgNAWMpoDRLDDCwWgKGOEJYDQFjKaA0SwwwsFoCgBshCcABgCdkAL/fkEcHQAAAABJRU5ErkJggg==",
|
||||
"text/plain": [
|
||||
"<PIL.BmpImagePlugin.BmpImageFile image mode=L size=256x256>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Message well hidden within : image_secrete.bmp\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/var/folders/qx/qc20ksl50kb3r1gbtqwgqm2h0000gn/T/ipykernel_3336/3844268843.py:25: DeprecationWarning: 'mode' parameter is deprecated and will be removed in Pillow 13 (2026-10-15)\n",
|
||||
" img_modifiee = Image.fromarray(pixels_modifies, mode='L')\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAEAAQABAREA/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/9oACAEBAAA/APBlnmO7Msh3IEbLHlRjAPsNo49h6Vcjv7wMjC7n3Iioh8w5VVIKgegBAIHYirEV/eLNFMt3OJYU2RuJDuRemAew5PA9auQatqUOPK1C7TCKg2zMPlXOB16DJwPenfa7mRQslxKwEYiwzk/IDkL9AQDjpVqO/vAyMLufciKiHzDlVUgqB6AEAgdiKcJHdUVnZgg2qCc7RknA9OST+NXjf3ksKwyXc7xKmxUaQlQvBwB6fKvHsPSpjd3M0axy3EsiKFVVZyQAudoA9snHpk1aW/vD5ebuc+Vt8v8AeH5NuduPTGTj0yatR6nfhoGF7cgwArCfNb92CMYXnjjjinRTzK0TLLIGh/1ZDHKc549OSTx3NWre7uYJIpIriWN4gVjZHIKA5yAe3U/masW93cwSRSRXEsbxArGyOQUBzkA9up/M1Yt7u5gkikiuJY3iBWNkcgoDnIB7dT+Zqzb3dzBJFJFcSxvECsbI5BQHOQD26n8zVa30ywgkikisraN4gVjZIlBQHOQDjjqfzNaaVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK+BkqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWUqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlfAyVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrKVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSvgZKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVlKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJXwMlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqylWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEqwlWEr4GSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVZSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCVYSrCV8DJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKspVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhKsJVhK/9k=",
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAAAAAB5Gfe6AAAC8UlEQVR4AWJkaGxkZARjxkbGRhBgBAmAhECiYBpEgGTB8mAOIyNYFUgFWBeY39gIZTdCFYNEQUIgxbhomOWMAwUYBsriQWIvE8MIB6MBMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEg9EUMMITwGgKGE0Bo1lghIPRFDDCE8BoChhNAaNZYISD0RQwwhPAaAoYTQGjWWCEA8BGfAoAADMZJv0gGr2bAAAAAElFTkSuQmCC",
|
||||
"text/plain": [
|
||||
"<PIL.BmpImagePlugin.BmpImageFile image mode=L size=256x256>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Message : Decode this!\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"display(Image.open(nom_fichier))\n",
|
||||
"# 2. Cacher le message\n",
|
||||
"cacher_messageGSB(nom_fichier, mon_message, nom_fichier_sortie)\n",
|
||||
"\n",
|
||||
"#display the image\n",
|
||||
"display(Image.open(nom_fichier_sortie))\n",
|
||||
"\n",
|
||||
"# 3. Extraire le message\n",
|
||||
"message_trouve = extraire_messageGSB(nom_fichier_sortie)\n",
|
||||
"print(f\"Message : {message_trouve}\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "sITRU6MzoIpA"
|
||||
},
|
||||
"source": [
|
||||
"Avec une clé"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "4vYMdWoxoIWZ"
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def generer_positions(cle, nb_bits_necessaires, max_pixels):\n",
|
||||
" # On transforme la clé (ex: 1369) en une liste d'entiers [1, 3, 6, 9]\n",
|
||||
" sauts = [int(chiffre) for chiffre in str(cle)]\n",
|
||||
"\n",
|
||||
" positions = []\n",
|
||||
" pos_actuelle = 0\n",
|
||||
"\n",
|
||||
" for i in range(nb_bits_necessaires):\n",
|
||||
" saut = sauts[i % len(sauts)]\n",
|
||||
" # Sécurité : si un chiffre de la clé est 0, on avance d'au moins 1\n",
|
||||
" # pour ne pas écraser le même pixel\n",
|
||||
" if saut == 0:\n",
|
||||
" saut = 1\n",
|
||||
"\n",
|
||||
" pos_actuelle += saut\n",
|
||||
"\n",
|
||||
" # On vérifie qu'on ne dépasse pas la fin de l'image\n",
|
||||
" if pos_actuelle >= max_pixels:\n",
|
||||
" raise ValueError(f\"The image is too small. It can only hold {i} bits with this key.\")\n",
|
||||
"\n",
|
||||
" positions.append(pos_actuelle)\n",
|
||||
"\n",
|
||||
" return positions\n",
|
||||
"\n",
|
||||
"# --- 2. ENCODAGE AVEC CLÉ ---\n",
|
||||
"\n",
|
||||
"def cacher_message_cle(chemin_image_entree, message_secret, cle, chemin_image_sortie):\n",
|
||||
" img = Image.open(chemin_image_entree).convert(\"L\")\n",
|
||||
" pixels_plats = np.array(img).flatten()\n",
|
||||
"\n",
|
||||
" message_binaire = texte_vers_binaire(message_secret + DELIMITEUR)\n",
|
||||
"\n",
|
||||
" # On génère exactement les positions dont on a besoin\n",
|
||||
" positions = generer_positions(cle, len(message_binaire), len(pixels_plats))\n",
|
||||
"\n",
|
||||
" # On remplace les LSB uniquement sur ces positions précises\n",
|
||||
" for i in range(len(message_binaire)):\n",
|
||||
" pos = positions[i]\n",
|
||||
" bit_a_cacher = int(message_binaire[i])\n",
|
||||
" pixels_plats[pos] = (pixels_plats[pos] & 254) | bit_a_cacher\n",
|
||||
"\n",
|
||||
" img_modifiee = Image.fromarray(pixels_plats.reshape(np.array(img).shape), mode=\"L\")\n",
|
||||
" img_modifiee.save(chemin_image_sortie, format=\"BMP\")\n",
|
||||
" print(f\"Hidden message found with key '{cle}' !\")\n",
|
||||
"\n",
|
||||
"# --- 3. DÉCODAGE AVEC CLÉ ---\n",
|
||||
"\n",
|
||||
"def extraire_message_cle(chemin_image, cle):\n",
|
||||
" img = Image.open(chemin_image).convert(\"L\")\n",
|
||||
" pixels_plats = np.array(img).flatten()\n",
|
||||
"\n",
|
||||
" sauts = [int(chiffre) for chiffre in str(cle)]\n",
|
||||
" pos_actuelle = 0\n",
|
||||
" index_saut = 0\n",
|
||||
"\n",
|
||||
" bits_extraits = \"\"\n",
|
||||
" message_decode = \"\"\n",
|
||||
"\n",
|
||||
" # On parcourt l'image en sautant de pixel en pixel selon la clé\n",
|
||||
" while pos_actuelle < len(pixels_plats):\n",
|
||||
" saut = sauts[index_saut % len(sauts)]\n",
|
||||
" if saut == 0: saut = 1\n",
|
||||
" pos_actuelle += saut\n",
|
||||
"\n",
|
||||
" if pos_actuelle >= len(pixels_plats):\n",
|
||||
" break\n",
|
||||
"\n",
|
||||
" # On extrait le bit\n",
|
||||
" bits_extraits += str(pixels_plats[pos_actuelle] & 1)\n",
|
||||
" index_saut += 1\n",
|
||||
"\n",
|
||||
" # Tous les 8 bits, on convertit en texte\n",
|
||||
" if len(bits_extraits) == 8:\n",
|
||||
" message_decode += chr(int(bits_extraits, 2))\n",
|
||||
" bits_extraits = \"\"\n",
|
||||
"\n",
|
||||
" # On s'arrête si on trouve le délimiteur\n",
|
||||
" if message_decode.endswith(DELIMITEUR):\n",
|
||||
" return message_decode[:-len(DELIMITEUR)]\n",
|
||||
"\n",
|
||||
" return \"No hidden message found.\"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"id": "pf1ydHiSpkno",
|
||||
"outputId": "3bf962b6-0169-4ad8-a168-2971c308174c"
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Hidden message found with key '1369' !\n",
|
||||
"Test right key : Try out keys!\n",
|
||||
"Test wrong key : No hidden message found.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/var/folders/qx/qc20ksl50kb3r1gbtqwgqm2h0000gn/T/ipykernel_3336/840764186.py:42: DeprecationWarning: 'mode' parameter is deprecated and will be removed in Pillow 13 (2026-10-15)\n",
|
||||
" img_modifiee = Image.fromarray(pixels_plats.reshape(np.array(img).shape), mode='L')\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"image_originale = \"image_test_8bits.bmp\"\n",
|
||||
"image_stego_cle = \"image_test_stego_cle.bmp\"\n",
|
||||
"mon_message = \"Try out keys!\"\n",
|
||||
"ma_cle = 1369\n",
|
||||
"\n",
|
||||
"# 1. On cache\n",
|
||||
"cacher_message_cle(image_originale, mon_message, ma_cle, image_stego_cle)\n",
|
||||
"\n",
|
||||
"# 2. On extrait avec la BONNE clé\n",
|
||||
"print(\"Test right key :\", extraire_message_cle(image_stego_cle, 1369))\n",
|
||||
"\n",
|
||||
"# 3. On extrait avec une MAUVAISE clé (ça devrait sortir n'importe quoi ou échouer)\n",
|
||||
"print(\"Test wrong key :\", extraire_message_cle(image_stego_cle, 4444))\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"provenance": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "studies (3.13.9)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.13.9"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0
|
||||
}
|
||||
BIN
M2/Cybersecurity/image_secrete.bmp
Normal file
BIN
M2/Cybersecurity/image_secrete.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
BIN
M2/Cybersecurity/image_test_8bits.bmp
Normal file
BIN
M2/Cybersecurity/image_test_8bits.bmp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
@@ -38,6 +38,7 @@
|
||||
|--------|-------------|
|
||||
| `Advanced Machine Learning` | Advanced ML techniques |
|
||||
| `Clustering In Practice` | Unsupervised learning and clustering |
|
||||
| `Cybersecurity` | Data security and analysis |
|
||||
| `Data Visualisation` | Data visualization principles and tools |
|
||||
| `Deep Learning` | Neural networks and deep architectures |
|
||||
| `Enjeux Climatiques` | Climate issues and data analysis |
|
||||
|
||||
Reference in New Issue
Block a user