Archive mensuelle 25 juin 2020

Un chatbot en Python

La logique d’un chatbot en Python n’est pas très compliquée à comprendre. Nous allons voir dans cet article l’essentiel de cette logique.

Fractions continues en Python

Les fractions continues constituent une notion plutôt intéressant en mathématiques. C’est une façon d’écrire les nombres. Dans cet article, je vais expliquer dans les grandes lignes la notion mathématique et dans un second temps, nous allons implémenter en Python une classe permettant de représenter une fraction continue et d’en obtenir sa valeur fractionnaire.

Stéganographie et Python

La stéganographie consiste à dissimuler un message dans un autre message. Dans cet article nous verrons une façon de dissimuler un texte dans une image à l’aide de Python.

Stéganographie avec Python
Stéganographie avec Python

Une méthode de stéganographie en Python

Je souhaite incruster les lettres “AB” dans l’image.

Code ASCII des caractères

Il faut d’abord que j’obtienne le code ASCII de chaque caractères. On l’obtient en Python avec la commande :

bin( ord( 'A' ) ) # donne : '0b1000001'
bin( ord( 'B' ) ) # donne : '0b1000010'

Il nous faut un octet donc on supprime le ‘0b’:

bin( ord( 'A' ) )[2:] # donne : '1000001'
bin( ord( 'B' ) )[2:] # donne : '1000010'

Il nous faut encore formater de sorte à bien avoir 8 binaires :

bin( ord( 'A' ) )[2:].rjust(8,'0') # donne : '01000001'
bin( ord( 'B' ) )[2:].rjust(8,'0') # donne : '01000010'

Séparation des niveaux de couleurs

Vous le savez peut-être, une image est composée de 3 ou 4 couches; on va simplifier en disant qu’elle contient 3 niveaux de couleurs : rouge, vert et bleu. On va donc, pour chaque pixel de l’image, récupérer le nombre associé au niveau rouge (par exemple), puis prendre le nombre pair qui lui est inférieur ou égal (si le pixel “0” est associé à 37, on va arrondir à 36 et s’il est associé à 42, on garde 42). Pour chaque pixel, je vais noter R[i] le résultat obtenu pour le pixel i.

Transformation de la valeur

Un tableau est préférable pour expliquer, car là, ça devient chiant à décrire avec des mots ce qui se passe :

Pixel12345678910111213141516
Image3071252010152159618202020208715101
Réduction3070242010152149618202020208614100
Binaire0100000101000010
Couverture3071242010152149718212020208615100
  • première ligne : représente le numéro du pixel de l’image;
  • deuxième ligne : représente le nombre associé au pixel i sur le niveau de rouge;
  • troisième ligne : représente l’arrondi au nombre pair inférieur ou égal;
  • quatrième ligne : représente les deux octets correspondant à ‘A’ et ‘B’ (le message à incruster);
  • dernière ligne : représente la somme des lignes 3 et 4, qui donne le nombre attribué au pixel i sur la couche rouge dans l’image finale, que l’on appelle généralement la couverture.

Ainsi, à l’œil nu, on ne remarque aucune altération de l’image puisque l’on ajoute uniquement 1 (au maximum) sur une seule couche.

Stéganographie en Python à l’aide de PIL

La première chose à savoir est que nous allons manipuler des images en Python et donc utiliser le module PIL. Il faut alors l’installer. Dans un terminal, taper (je suis sous Python 3.8+) :

pip install Pillow

Incruster un message dans une image (stéganographie python)

Voici la définition de la fonction:

from PIL import Image

def stegano(name_img , msg):
    im = Image.open(name_img)
    # on récupère les dimensions de l'image
    w , h = im.size

    # on sépare l'image en trois : rouge, vert et bleu
    r , g , b = im.split()

    # on transforme la partie rouge en liste
    r = list( r.getdata() )

    # on calcule la longueur de la chaîne et on la transforme en binaire
    u = len(msg)
    v = bin( len(msg) )[2:].rjust(8,"0")

    # on transforme la chaîne en une liste de 0 et de 1 
    ascii = [ bin(ord(x))[2:].rjust(8,"0") for x in msg ]

    # transformation de la liste en chaîne
    a = ''.join(ascii)

    # on code la longueur de la liste dans les 8 premiers pixels rouges
    for j in range(8):
        r[j] = 2 * int( r[j] // 2 ) + int( v[j] )

    # on code la chaîne dans les pixels suivants
    for i in range(8*u):
        r[i+8] = 2 * int( r[i+8] // 2 ) + int( a[i] )
        
    # on recrée l'image rouge 
    nr = Image.new("L",(16*w,16*h))
    nr = Image.new("L",(w,h))
    nr.putdata(r)

    # fusion des trois nouvelles images
    imgnew = Image.merge('RGB',(nr,g,b))
    new_name_img = "couv_" + name_img
    imgnew.save(new_name_img)

En tapant:

stegano("grand_pere_a_la_plage.png" , "Il a mangé trop de cassoulet !")

le message est incrusté dans l’image et la couverture est sauvegardée sous le nom “couv_grand_pere_a_la_plage.png”.

Obtention du message

def get_msg(name_couv):
    im = Image.open(name_couv)
    r , g , b = im.split()
    r = list( r.getdata() )
    
    # lecture de la longueur de la chaine
    p = [ str(x%2) for x in r[0:8] ]
    q = "".join(p)
    q = int(q,2)
    
    # lecture du message
    n = [ str(x%2) for x in r[8:8*(q+1)] ]

    b = "".join(n)
    message = ""

    for k in range(0,q):
        l = b[8*k:8*k+8]
        message += chr(int(l,2))
        
    return message

À noter que n’importe qui peut obtenir le message… Ce n’est donc pas très sécurisé. Cette technique est donc à coupler avec une technique de cryptographie pour chiffrer et déchiffrer le message…

Extraire le code \(\LaTeX\) entre deux balises avec Python

5h12 du matin: je n’arrive pas à me rendormir… Je viens d’avoir une idée en tête et comme je ne suis pas procrastinateur, je me lève pour la concrétiser. L’idée du jour (enfin… de la nuit): comment extraire automatiquement la portion de code \(\LaTeX\) contenue entre deux balises \begin{python} et \end{python}, et enregistrer cette portion de code dans un fichier, le tout avec Python ?

Les délires d’Eulaire

Une fois n’est pas coutume… Je vais parler d’une page Facebook que j’ai créée pendant le confinement de 2020, et sur laquelle je mets tous les délires qui passent par ma tête.

Dans la vie, il n’y a pas que les maths, ni l’informatique… Il faut savoir décompresser ! J’ai un humour très particulier, et il ne plaît pas à tout le monde !

Voici quelques “délires” pour vous donner une idée:

Si ce genre d’humour vous plaît, abonnez-vous : https://www.facebook.com/DelireDeulaire

Python, tkinter et calculatrice

Je viens de faire une calculatrice basique à l’aide de Python et de tkinter.

Génération aléatoire d’un identifiant en Python

Vous le savez peut-être si vous consultez souvent ce site, j’adore générer automatiquement (voir cet article ou encore celui-ci). Dans cet article, je vais parler de génération aléatoire d’identifiant (unique et multiple) en Python.

Supportscreen tag