Exercices: représentation des entiers positifs

Exercice 1: écrire les entiers positifs donnés dans la base souhaitée

Recopier et compléter le tableau suivant:

Décimal Binaire Hexadécimal
11
11
11
22
1010
1010
54
10101
AA
2988

Exercice 2: nommer une couleur

Comme nous l’avons déjà vu, une couleur dans le système RVB (ou RGB dénomination en anglais) a trois composantes (rouge, vert, bleu)rouge, vert et bleu sont trois entiers entre 0 et 255 en écriture décimale.

Combien de bits sont nécessaires pour écrire un entier entre 0 et 255 ? Combien d’octet(s) cela représente ?

Toutefois, vous le savez certainement, une couleur peut être nommée sous la forme #.......

En restant sur cette page,

  • placer votre souris sur la question suivante;
  • cliquer droit avec votre souris ;
  • sélectionner “Examiner l’élément”.

Quelle est le nom de la couleur utilisée pour écrire cette présente question ?

En fait, #...... est l’écriture hexadécimale de (rouge, vert, bleu). En détail,

  • les deux premiers chiffres qui suivent le # est la composante rouge écrite en hexadécimal;
  • les deux suivants correspondent à la composante vert
  • et vous l’aurez compris que les deux dernières sont associées à bleu.

Reprendre la nom de la couleur de la question précédente en #..... et retrouver son nom dans le système RVB (valeur de chacune des composantes).

Vous pourrez vérifier que la couleur trouvée est nécessairement bleutée au regard des ordres de grandeurs des valeurs obtenues.

Retrouver la teinte de la couleur désignée par #C836C8.

Quel est le nom de l’élement de cette page admet pour couleur (251, 240, 203) ?

Exercice 3: jouer avec les différents encodages des caractères

Les encodages UTF-8 et latin 1 (ISO-8859-1) prolongent l’encodage ASCII: les caractères ASCII ont le même code dans les 2 autres encodages.

Ci-dessous le tableau des codes en hexadécimal dans l’encodage ISO-8859-1.

0 1 2 3 4 5 6 7 8 9 A B C D E F
0
1
2 espace ! " # $ % & ' ( ) * + , - . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ A B C D E F G H I J K L M N O
5 P Q R S T U V W X Y Z [ \ ] ^ _
6 ` a b c d e f g h i j k l m n o
7 p q r s t u v w x y z { } ~
8
9
A ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ® ¯
B ° ± ² ³ ´ µ · ¸ ¹ º » ¼ ½ ¾ ¿
C À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï
D Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß
E à á â ã ä å æ ç è é ê ë ì í î ï
F ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ

On donne l’extrait d’un texte encodé en UTF-8 en hexadécimal: 43 65 74 20 61 69 72 20 65 73 74 20 65 6e 74 c3 aa 74 61 6e 74 2e.

  1. Déterminer comment ce texte serait affiché s’il était interprété en ISO-8859-1.

  2. En déduire le code correspondant au caractère ê en UTF-8 en hexadécimal, puis en binaire.

Exercice 4: tables de vérité de booléens

  1. Recopier et compléter la table de vérité ci-dessous.

    \(a\) \(b\) \(c\) \( \text{NOT } c\) \(b \text{ AND NOT } c\) \(a \text{ XOR } (b \text{ AND NOT } c)\)
    \(0\) \(0\) \(0\)
    \(0\) \(1\) \(0\)
    \(1\) \(0\) \(0\)
    \(1\) \(1\) \(0\)
    \(0\) \(0\) \(1\)
    \(0\) \(1\) \(1\)
    \(1\) \(0\) \(1\)
    \(1\) \(1\) \(1\)
  2. Est ce que \(a \text{ XOR } (b \text{ AND NOT } c)\) et \((a \text{ XOR } b) \text{ AND } (a \text{ XOR NOT } c)\) désigne le même booléen ?

Correction

Exercice 5: opérations sur les entiers

Donner le résultat des opérations suivantes en binaire et en décimal.

  1. \( 11011_2 + 1010_2 \) ;
  2. \(11011_2 \text{ & } 1010_2\) ;
  3. \( 11011_2 \mid 1010_2 \) ;
  4. \(11011_2 \wedge 1010_2\) ;
  5. \(\sim 101011_2\) dans les entiers à 1 octet ;
  6. \( 54_{10} \text{ & } 14_{16} \) ;
  7. \( ( 11_2 \ll 2 ) \text{ & } 101_2 \) ;
  8. \( 10_2 \mid (\sim 1011_2 \wedge 101_2) \) dans les entiers à 1 octet.

Aide: le cas échéant, il faudra obtenir l’écriture binaire des nombres données.

Correction

Exercice 6: / la stéganographie

La stéganographie est l’art de la dissimulation : son objet est de faire passer inaperçu un message dans un autre message. On va s’intéresser à la méthode, nommée LSB (Least Significant Bits ou bits de poids faible). Elle consiste à cacher un nombre dans un autre, et comme le monde informatique est bien fait (toutes les données sont représentées par des nombres), on va l’appliquer aux images, plus exactement, aux composantes de la couleur (en RVB) de chacun des pixels qui les composent.

Méthode LSB:

Supposons que l’on dispose de deux nombres (de 8 bits, c’est-à-dire 1 octet) \(\texttt{secret} = 241_{10} = 11110001_2\) et \(\texttt{masque} = 33_{10} = 00100001_2 \) et que l’on souhaite cacher le nombre secret dans le nombre masque pour ce faire nous allons fabriquer un troisième nombre proche de masque de la façon suivante:

  • ce nombre s’écrira aussi sur 1 octet de la forme \(…….._2\);

  • les 5 bits de poids fort seront ceux de masque (ce qui nous assure que les deux nombres soient proches): \(\fbox{00100}…_2\);

  • les 3 bits restants de poids faible seront les 3 bits de poids fort du nombre que l’on cherche à dissimuler: \(00100\fbox{111}_2\).

Le nombre ainsi créée est \(00100111_2 = 39_{10}\).

Créer un fichier nommé steganographie.py, puis y écrire une fonction que vous nommerez lsb_masquer() qui agit comme décrit ci-dessus.

Jeu de test:

    >>> lsb_masquer(241, 33)
    39

Ensuite ? Ne reste plus qu’à retrouver le nombre de départ à partir de ce \(39 = 00100111_2\). Mais le peut-on ? Clairement, non ! On ne retrouve que partiellement le nombre. De part la création de ce \(39\), le nombre que l’on cherche à démasquer s’écrit de la forme \(111….._2\) (on a récupéré les 3 bits de poids faible de \(39 = 00100\fbox{111}_2\)). Le reste ne peut être retrouvé totalement.Finalement, ce nombre est entre \(11100000_2\) et \(11111111_2\). Dans le doute, prenons le nombre central, c’est-à-dire \(11110000_2 = 240_{10}\). Oui ce n’est pas le nombre de départ, mais on n’est pas très éloigné.

Écrire une fonction que vous nommerez lsb_demasquer() qui retourne un nombre suivant le procédé décrit.

Jeu de test:

    >>> lsb_demasquer(39)
    240

Appliquons ceci aux images !

Masquer une image …

Une image en JPEG n’est qu’une succession de pixels de couleurs en RVB lesquelles ne sont des tuples comme nous l’avons déjà vu. En Python, le module PIL par exemple de lire la couleur d’un pixel, mais aussi de créer un pixel dans une image.

À titre d’exemple:

1
2
3
4
5
6
7
from PIL import Image

nimg = Image.new("RGB", (150, 100))   # permet de créer une nouvelle image de
dimensions 150 px sur 100 px dont le système de couleur est en RVB

nimg.putpixel((85, 50), (0, 255, 0)) # permet de modifier la couleur du pixel en
position (85, 50), la couleur passe en (0, 255, 0) (autrement dit en vert).

Par ailleurs, il est fortement conseillé de faire usage des fonctions sur lesquelles vous avez déjà travaillé dans un chapitre précédent. Elles devraient être contenues dans le fichier image.py (si vous ne l’avez pas renommé). Pour ce faire, la méthode la plus simple est de copier ce fichier image.py contenant vos fonctions (si vous avez un doute sur votre fichier, vous pouvez le récupérer ci-dessous), de le coller dans le dossier qui contient déjà votre fichier steganographie.py, puis de l’importer comme tout module Python avec import image ou from image import *.

  • image.py (1 ko)
  • Retournons à notre exercice sur les images.

    Le principe sera, pixel par pixel, de mélanger les coumeurs par application de la fonction lsb_masquer sur chaque composante des couleurs des pixels dans la même position sur les deux images afin de créer une nouvelle image de sorte de mettre le plus de poids sur le masque et moins sur l’image que l’on cherche à cacher. On obtiendra une pâle copie du masque d’origine, mais imperceptible à l’oeil humain.
    Pour finir, on extrairera une version nécessairement altérée de l’image secrète à partir de l’image créée précédemment par application de lsb_demasquer sur chaque composante des couleurs de ses pixels.

  • masque.jpg (168 ko)
  • secret.jpg (32 ko)
  • Télécharger les deux images secret.jpg et masque.jpg et placer les dans le même dossier que vos fichiers image.py et steganographie.py.

    Vérifier que ces deux images ont effectivement la même taille. Vous pouvez pour ce point faire appel à l’une des fonctions déjà présente dans image.py.

    Écrire une fonction nommée masquer_image() admettant comme paramètre img_secret et img_masque (les deux images de départ) qui retourne une nouvelle image comme exposé ci-dessus. Vous pouvez à la suite appliquer cette fonction aux images obtenues dans la question 1. N’oubliez pas que vous disposez des fonctions afficher() et sauver() du module image.

    Jeu de test:

        >>> from PIL import Image
        >>> img1 = Image.open("secret.jpg")
        >>> img2 = Image.open("masque.jpg")
        >>> nimg = masquer_image(img1, img2)
        >>> nimg.getpixel((170, 140))
        (39, 63, 8)

    Écrire une fonction nommée demasquer_image() qui admet comme paramètre une image img et qui retourne une nouvelle image vérifiant la consigne.

    Jeu de test:

        >>> from PIL import Image
        >>> img1 = Image.open("secret.jpg")
        >>> img2 = Image.open("masque.jpg")
        >>> nimg1 = masquer_image(img1, img2)
        >>> nimg2 = demasquer_image(nimg1)
        >>> nimg2.getpixel((170, 140))
        (240, 240, 16)