def get_info(wave_data): """Retourne quelques valeurs utiles contenues dans l'encodage du fichier WAVE. Dans l'ordre : - nbr de canaux - frequence d'échantionnage - nbr de bits par échantillon NB : Dans un fichier WAV, les 44 premiers octets sont des bits qui donnent les paramètres du fichier. """ val = "" for i in wave_data[22:24]: #Nombre de canaux val = c.to_binary(i, 8) + val nbr_canaux = c.to_decimale(val) val = "" for i in wave_data[24:28]: #Frequence d'échantillonage val = c.to_binary(i, 8) + val freq_ech = c.to_decimale(val) val = "" for i in wave_data[34:36]: #Bits par échantillonage val = c.to_binary(i, 8) + val bits_ech = c.to_decimale(val) print("Nombre de canaux :", nbr_canaux) print("Frequence d'échantillonnage : {} Hz".format(freq_ech)) print("Nombre de bits par échantillon :", bits_ech) return nbr_canaux, freq_ech, bits_ech
def desteganographie(chemin_i, chemin_dossier=''): """Récupère un fichier caché dans une image à partir des LSB. chemin_i représente l'image dans laquelle chercher le fichier. """ taille_tot = taille_nbr_bits + taille_name image = Image.open(chemin_i) di = image.getdata() print("Passage des tuples de l'image en listes...") di = convert_tuple_to_list(di) print("Passage en bits et récupération des infos du fichier caché...") for i in range(taille_nbr_bits + taille_name): pixel = int(i / 3) canal = i % 3 di[pixel][canal] = to_binary(di[pixel][canal], 8) df = get_LSB(di, taille_nbr_bits) nbr_bits_f = "" for i in df: nbr_bits_f += i nbr_bits_f = to_decimale(nbr_bits_f) taille_tot += nbr_bits_f print("Nombre de bits du fichier :", nbr_bits_f) for i in range(taille_name + taille_nbr_bits, nbr_bits_f + taille_name + taille_nbr_bits): #Convertion du bon nombre de bits pixel = int(i / 3) canal = i % 3 di[pixel][canal] = to_binary(di[pixel][canal], 8) print("Récupération des LSB dans l'image...") name_f = get_LSB(di, nbr_bits=taille_name, bit_start=taille_nbr_bits) df = get_LSB(di, nbr_bits=nbr_bits_f, bit_start=taille_name + taille_nbr_bits) print("Conversion du nom du fichier en caractères...") name_f = convert_bits_to_bytes( name_f) #Renvoi les valeurs décimales des paquets de 8 bits n = "" for i in name_f: n += chr(i) #Converti les valeurs décimales en caractères (ASCII) name_f = str(n) n = "" for i in name_f: if i != '\x00': #Caractère vide qui a pu être créée lors du codage dans l'image du nom (lors de l'ajustement de la taille du nom) n += i print("Nom du fichier :", n) print("Création du fichier...") df = convert_bits_to_bytes(df) create_file(df, chemin_dossier + n) print("Fini !")
def steganographieV2(image_cover, secret_image): """Permet de cacher une image de type 'RGB' dans une autre image 'RGB' en la passant auparavant en gris et en réduisant la qualité. Il faut que la taille de l'image a caché soit inferieur à celle de l'image à cacher. Pour être plus précis, il faut que : longueur_s * largeur_s * 3 + 22 < longueur_c * largeur_c * 3""" if image_cover.mode != 'RGB' or secret_image.mode != 'RGB': print("Images are not in 'RGB' mode") return None longueur, largeur = secret_image.size L, l = image_cover.size taille_information_s = largeur * longueur * 3 + 22 taille_information_c = l * L * 3 if taille_information_s > taille_information_c: print("L'image a caché est trop grosse par rapport à l'image_cover.") return None data = secret_image.getdata() data_cover = image_cover.getdata() print("Conversion des tuples en listes...") data_cover = convert_tuple_to_list(data_cover) print("Passage en bits de l'image_cover...") for i in range(taille_information_s): for j in range(3): data_cover[i][j] = to_binary(data_cover[i][j], 8) print("Insertion de la taille de l'image (", longueur, "x", largeur, ")...", sep="") longueur = to_binary(longueur, 11) largeur = to_binary(largeur, 11) data_cover = put_LSB(data_cover, longueur + largeur, bit_start=0) print("Conversion en gris et récupération des bits...") data = recup_data(data) print("Insertion des bits dans les LSB...") data_cover = put_LSB(data_cover, data, bit_start=22) print("Repassage en décimal...") for i in range(taille_information_s): for j in range(3): data_cover[i][j] = to_decimale(data_cover[i][j]) print("Repassage en tuple...") data_cover = convert_list_to_tuple(data_cover) print("Sauvegarde de l'image...") image_cover = Image.new("RGB", image_cover.size) image_cover.putdata(data_cover) image_cover.save("stegano_image.bmp") print("Fini !")
def desteganographieV2(secret_image): """A besoin d'une image RGB pour que la fonction marche""" if secret_image.mode != 'RGB': print("Image not in 'RGB' mode") return None data = secret_image.getdata() print("Conversion des tuples en listes...") data = convert_tuple_to_list(data) for i in range(22): pixel = int(i / 3) canal = i % 3 data[pixel][canal] = to_binary(data[pixel][canal], 8) print("Récupération de la taille de l'image...") size = get_LSB(data, nbr_bits=22, bit_start=0) longueur = "" largeur = "" longueur = to_decimale(size[:11]) largeur = to_decimale(size[11:]) secret_data = list() print("La longueur de l'image est :", longueur) print("La largeur de l'image est :", largeur) print("Récupération des LSB...") for i in range(22, longueur * largeur * 3 + 22): #Converti uniquement les pixels interessants en bits pixel = int(i / 3) canal = i % 3 data[pixel][canal] = to_binary(data[pixel][canal], 8) temp = get_LSB(data, longueur * largeur * 3, 22) print("Taille de l'information en bits : ", len(temp)) j = 0 i = 0 while i < len( temp ) / 3: #Divise le tableau en un tableau groupé par 3 bits (3bits = 1 pixel gris) secret_data.append(temp[j] + temp[j + 1] + temp[j + 2]) secret_data[i] = to_decimale(secret_data[i]) secret_data[i] *= 255 / 7 #Passage du pixel gris à une echelle sur 255 i += 1 j = i * 3 print("Sauvegarde de l'image...") secret_image = Image.new("L", (longueur, largeur)) secret_image.putdata(secret_data) secret_image.save("secret_image.bmp") print("Fini !")
def desteganographie(cover_im): """Il faut une image RGB""" if cover_im.mode != "RGB": print("Error, the image is not in an RGB mode") return None print("Récupération de la data de l'image...") data = cover_im.getdata() print("Enlèvement des tuples de la data...") data = convert_tuple_to_list(data) grey_data = list() print("Récuperation de la data dans l'image...") for i in range( len(data) ): #Récupère tout les pixels de l'image et les changes en bits for j in range(3): data[i][j] = to_binary(data[i][j], 8) #Passage en bits grey_data.append("" + data[i][0][7] + data[i][1][7] + data[i][2][7]) #Récupère les LSB de l'image cover grey_data[i] = to_decimale(grey_data[i]) #Retour en décimale grey_data[i] *= 255 / 7 #Retour à une bonne échelle de gris print("Sauvegarde de la nouvelle image...") grey_image = Image.new("L", cover_im.size) #Nouveau mode : mode greyscale grey_image.putdata(grey_data) grey_image.save("secret_image.bmp") print("Fini !")
def create_key(): """Créé une clef de 64 bits dont les bits 8-16-24...64 sont des bits de parité, de sorte que les bytes aient un nombre impaire de 1.""" key = randbits(56) #Nombre aléatoire de 56 bits key = to_binary(key, 56) cnt = 0 sous_key = [] for i in range(8): sous_key.append( key[i * 7:(i + 1) * 7]) #Sépare en 8 sous tableaux de 7 bits (8*7 = 56) for i in range(len(sous_key)): #Parcourt les sous-tableaux for j in range(len(sous_key[i])): if sous_key[i][j] == '1': cnt += 1 #Compteur pour la parité sous_key[i] += str( (cnt + 1) % 2 ) #On ajoute un dans le cas où notre nombre est pair, sinon 0 si le nombre est impair cnt = 0 key = "" for i in range(len(sous_key)): for j in range(len(sous_key[i])): key += sous_key[i][ j] #Ajoute enfin toutes les sous-clefs en une seule clef return key
def subs(B, i): """Applique la S-box numéro i sur les 6-bits B.""" colonne = to_decimale(B[1:5]) #4 bits centraux ligne = to_decimale(B[0] + B[-1]) #2 bits extrêmes B = to_binary(S[i][ligne][colonne], 4) #4 bits de sortie return B
def convert_bytes_to_bits(data): """Renvoi une liste de bits réunis dans une seule string.""" n_data = "" for i in range(len(data)): n_data += to_binary(data[i], 8) return n_data
def from_oct_to_bit(octets): bits = [] for i in octets: word = c.to_binary(i, 8) for b in word: bits.append(int(b)) return bits
def steganographie(cover_im, secret_im): """Les images doivent être toutes les deux de la même taille et en RGB""" if (cover_im.size != secret_im.size) or (cover_im.mode != secret_im.mode): print( "Error, images do not have the same size or are not in 'RGB' mode") return None #grey_im = convert_grey(secret_im, save = True)#Change l'image en gris #data = convert_255_to_7(grey_im.getdata())#Réduit la qualité de l'image data = secret_im.getdata() data_cover = cover_im.getdata() print("Passage des tuples en liste pour le traitement...") data_cover = convert_tuple_to_list( data_cover) #Enlève les tuples pour traiter les pixels print("Traitement des data et insertion dans la data_cover...") for i in range(len(data_cover)): grey_data = (data[i][0] + data[i][1] + data[i][2]) / 3 #Conversion en gris grey_data = convert_255_to_7( grey_data ) #Passage à une échelle plus petite (perte d'information) grey_data = to_binary(grey_data, 3) #Passage en bits for j in range(3): data_cover[i][j] = to_binary(data_cover[i][j], 8) #Passage en bits data_cover[i][j] = data_cover[i][j][:-1] + grey_data[ j] #Remplacement du dernier bit par la valeur du bit de data data_cover[i][j] = to_decimale( data_cover[i][j]) #Repasse en décimale print("Repassage en tuple pour la sauvegarde de l'image...") data_cover = convert_list_to_tuple( data_cover) #Remets les tuples pour la création de la nouvelle image print("Sauvegarde de la nouvelle image...") cover_im = Image.new("RGB", cover_im.size) cover_im.putdata(data_cover) cover_im.save("stegano_image" + ".bmp") print("Fini !")
def convert_bytes_to_bits(data): """Converti des données numériques en paquet d'octets en bits. Ce qui est retourné est une string contenant toute la data en bits. """ n_data = "" for i in range(len(data)): n_data += to_binary(data[i], 8) return n_data
def Vernam(bits, key=-1): """Permet de crypter des bits grâce à une clef et un XOR appliqué aux bits. key est un paramètre optionnel, si une clef est donnée en paramètre alors le programme va décrypter les données sinon il crypte les données et renvois les données cryptées ainsi que la clef """ if key == -1: key = randbits(len(bits)) key = to_binary(key, len(bits)) return XOR(bits, key), key else: return XOR(bits, key)
def recup_data(data): """Retourne un tableau avec uniquement les bits utiles""" new_data = list() temp = 0 for i in range(len(data)): temp = (data[i][0] + data[i][1] + data[i][2]) / 3 #Passage en gris temp = convert_255_to_7( temp) #Changement d'échelle et réduction de la qualité temp = to_binary(temp, 3) #Changement en binaire for j in range(3): new_data.append(temp[j]) #Ajout dans le noveau tableau return new_data
def steganographie(chemin_f, chemin_i, chemin_dossier=''): """Cache un fichier dans une image grâce aux LSB. chemin_f est le chemin du fichier à cacher. chemin_i est le chemin de l'image dans laquelle est caché le fichier. """ taille_tot = taille_nbr_bits + taille_name image = Image.open(chemin_i) di = image.getdata() print("Récupération de la data du fichier...") df, name_f = read_file(chemin_f) print("Passage de la data en bits...") df = convert_bytes_to_bits(df) n = "" #Nom du fichier codé en bits for i in name_f: #Ajoute le nom changé en bits dans n temp = ord(i) temp = to_binary(temp, 8) n += temp if len(n) > taille_name: #Vérifie si le nom n'est pas trop long print("Taille du nom du fichier supérieur à {} bits !".format( taille_name)) return None name_f = n for i in range(len(name_f), taille_name): #Ajuste pour avoir 80 bits de data name_f = '0' + name_f nbr_bits = len(df) taille_tot += nbr_bits print("Nombre de bits :", nbr_bits) capacite_i = len( di) * 3 #Multiplie par trois car chaque pixels peuvent contenir 3 bits print("Capacité de l'image :", capacite_i, "bits.") if capacite_i < taille_tot: print("L'image est trop petite pour le fichier (taille des infos :", taille_tot, "bits).") return None print("Converti les tuples de l'image en listes...") di = convert_tuple_to_list(di) print("Passage en bits des pixels de l'image...") for i in range(0, taille_tot, 3): pixel = int(i / 3) for j in range(3): di[pixel][j] = to_binary(di[pixel][j], 8) print("Ajout de la data du fichier dans l'image...") di = put_LSB(di, to_binary(nbr_bits, taille_nbr_bits), 0) #Commmence à écrire à 0 di = put_LSB(di, name_f, taille_nbr_bits) #Commence à écrire après le nombre de bits di = put_LSB(di, df, taille_name + taille_nbr_bits ) #Commence à écrire après les deux premières opérations print("Retour en décimal des pixels de l'image...") for i in range(0, taille_tot, 3): pixel = int(i / 3) for j in range(3): di[pixel][j] = to_decimale(di[pixel][j]) print("Retour en tuples...") di = convert_list_to_tuple(di) print("Sauvegarde de l'image (stegano_image.bmp)...") image = Image.new("RGB", image.size) image.putdata(di) image.save(chemin_dossier + "stegano_image" + ".bmp") print("Fini !")
def convert_ASCII_to_key(key): n_key = "" for i in key: n_key += to_binary(ord(i), 8) return n_key