You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/fontain.md
+75-64Lines changed: 75 additions & 64 deletions
Original file line number
Diff line number
Diff line change
@@ -1,91 +1,80 @@
1
-
Title: Transferer un gros fichier avec une fontaine de QR code
1
+
Title: Transférer un fichier via une fontaine de QR code
2
2
Slug: code-fontain
3
-
Date: 2024-09-30 19:30:31
4
-
Modified: 2024-09-30 19:30:31
3
+
Date: 2024-10-28 19:30:31
4
+
Modified: 2024-10-28 19:30:31
5
5
Tags: algorithme
6
6
Category: informatique
7
7
Author: Sacha schutz
8
-
SIDEBARIMAGE:images/common/term_banner.jpeg
8
+
SIDEBARIMAGE:images/common/fontain_banner.png
9
9
10
10
11
-
Serait il possible d'envoyer un fichier de 10 Mo en utilisant uniquement des QR codes ?
12
-
C'est la question que je me suis posé lorsque l'on m'a affirmé qu'il n'était
13
-
pas possible d'extraire des données d'une instance Jupyter tournant dans un bureau virtuel.
14
-
Dans cette bulle, un datascientist est censé pouvoir faire des analyses mais il lui est impossible
15
-
de récupérer des données.
16
-
Cependant, les données qui s'affiche sur un écran transitent forcement par la carte graphique de l'utilisateur.
17
-
Un hacker pourrait donc très probablement récupérer l'intégralité d'un gros fichier en faisant
18
-
juste des captures d'écran. J'ai donc voulu tester cette théorie en essayant de transferer un fichier de 10 Mo
19
-
à partir d'une vidéo d QR codes générés grâce à un algorithmes très interessant : Le code fontaine de Luby.
11
+
Serait-il possible d’envoyer un fichier de 10 Mo en utilisant uniquement des [QR codes](https://fr.wikipedia.org/wiki/Code_QR) ? C’est la question que je me suis posé lorsque l’on m’a affirmé qu’il était impossible d'extraire des données d’une instance [Jupyter](https://fr.wikipedia.org/wiki/Jupyter) fonctionnant dans un [bureau virtuel](https://fr.wikipedia.org/wiki/Bureau_virtuel_(travail)).
20
12
13
+
Dans cet genre d'environnement, un data scientist est censé pouvoir effectuer des analyses, mais il lui est impossible de récupérer les données. Cependant, les données affichées à l’écran transitent forcément par la carte graphique de l’utilisateur, ce qui signifie qu’un pirate pourrait potentiellement récupérer l’intégralité d’un fichier volumineux en réalisant simplement des captures d’écran.
14
+
15
+
J’ai donc voulu tester cette théorie en tentant de transférer un fichier de 10 Mo à partir d’une séquence vidéo de QR codes, générée grâce à un algorithme particulièrement ingénieux : [le code fontaine de Luby](https://en.wikipedia.org/wiki/Luby_transform_code).
21
16
22
17
## Encoder des données dans un QR Code
23
18
24
-
La capacité de stockage d'un QR code varie en fonction de sa version et de son niveau de code d'erreur.
25
-
Dans le meilleurs des cas, nous allons pouvoir stocker 2953 octects en version 40 ( 177 x 177 )
26
-
en utilisant un niveau de correction d'erreur Low ( 7% ).
27
-
Nous sommes loin des 10 Mo souhaités. Pour y rémedier il va donc falloir généré plein de QR code que l'on
28
-
pourra transmettre dans une vidéo. Supposions que je génère 30 QR code par secondes, je pourrais récupérér
29
-
des données à une vitesse de 720 Kbits/s (3000 * 30 * 8 * 10**-3) de quoi faire pallir mon bon view modem 56K.
30
-
Et voilà ce que ça donne pour un fichier de 10 Ko.
19
+
La capacité de stockage d’un QR code varie en fonction de sa version et de son niveau de correction d'erreur. Dans le meilleur des cas, un QR code en version 40 (177 x 177) avec un niveau de [correction d'erreur](https://dridk.me/reed-solomon.html) faible (7 %) peut stocker jusqu’à 2 953 octets. Nous sommes encore loin des 10 Mo souhaités. Pour y remédier, il est donc nécessaire de générer plusieurs QR codes, que l’on pourra transmettre en masse dans un flux en stream ou via une vidéo.
20
+
21
+
Supposons que je génère 30 QR codes par seconde ; je pourrais ainsi récupérer des données à une vitesse de 480 Kbits/s (2 000 octets * 30 * 8 * 10⁻³). On est certes loin des vitesses de la fibre optique, mais au-dessus des performances d’un modem 56K.
Animation d'un QR Code en version 40 encodant un fichier de 100 Ko.
24
+
Animation à 30 frame par secondes de plusieurs QR code en version 40 encodant un fichier de 100 Ko.
34
25
</div>
35
26
</div>
36
27
37
28
38
29
## Utilisation du code fontaine
39
-
Placons nous maintenant du coté du recepteur. Il suffirait en principe de faire des capture d'ecran toutes
40
-
les 4 ms et décoder chaque QR Code dans le bon ordre. Mais en réalité, il y a de forte chance d'en rater certain.
41
-
Dans des protocoles classiques de communication réseau bi-directionnel comme TCP/IP, chaque capture ou paquet doit
42
-
être confirmer à l'emetteur avant de recevoir le prochain. Dans notre cas, ce n'est pas possible
43
-
car la communication est unidirectionnel, nous ne faisons qu'écouter.
44
-
Une solution serait donc de demander à l'emetteur de répéter en boucle son message. Mais attendre un tour complet
45
-
pour récupérer un seul paquet risque d'être long.
46
-
La solution c'est d'utiliser un code fontaine, qui consiste à générer aléatoirement des paquets de données labelisé
47
-
et les emettre constamment comme une "fontaine de paquet". Le recepteur aura juste à collecter les paquets
48
-
dans le desordre puis les réassembler. Une implementation très bien optimisé du code fontaine est le code de transformation
49
-
de Luby ou code LT
30
+
Plaçons-nous maintenant du côté du récepteur. En principe, il suffirait de faire des captures d’écran toutes les 4 ms pour décoder chaque QR code dans le bon ordre. Mais en pratique, il est très probable que certains QR codes soient manqués. Dans les protocoles classiques de communication réseau bidirectionnelle, comme [TCP](https://fr.wikipedia.org/wiki/Transmission_Control_Protocol), chaque capture ou [paquet](https://fr.wikipedia.org/wiki/Paquet_(r%C3%A9seau)) doit être confirmé par le récepteur avant d’envoyer le suivant. Ici, ce n’est pas envisageable, car notre communication est unidirectionnelle : nous ne faisons qu’écouter.
31
+
32
+
Une solution pourrait consister à demander à l'émetteur de répéter son message en boucle. Cependant, attendre un cycle complet pour récupérer un seul paquet manqué serait inefficace.
33
+
34
+
La solution réside dans l'utilisation d'un [code fontaine](https://fr.wikipedia.org/wiki/Code_d%27effacement#Codes_fontaine_quasi-optimaux) qui génère des paquets de données aléatoires, étiquetés, qui sont émis continuellement comme une *fontaine de paquets*. Le récepteur n’a alors qu’à collecter les paquets dans le désordre et les réassembler.
35
+
36
+
Il existe une implémentation de code fontaine très efficace, appelée [transformation de Luby](https://en.wikipedia.org/wiki/Luby_transform_code) (ou code LT), que nous allons utiliser. Voici comment elle fonctionne.
50
37
51
38
### Fonctionnement de l'algorithme de Luby
52
39
53
40
Un code LT fonctionne de la façon suivante:
54
41
55
42
#### Emetteur
56
-
- Le message à transmettre est d'abord découpé en plusieurs bloc source de la même taille.
57
-
- Un tirage aléatoire est ensuite réalisé pour selectionné N bloc source.
58
-
- Ce tirage aléatoire suit une distribution de Soliton. ( Voir image )
59
-
- Ces N blocs sources sont combiné ensemble avec un operateur XOR pour former un seul bloc.
60
-
- Ce bloc encodé est alors transféré au recepteur en précisant le nombre de bloc source qu'il contient dans un identifiant.
61
-
- Dans notre cas, ce bloc est transféré via un QR code en reservant les 12 premiers bytes pour l'identifiant.
43
+
44
+
- Le message à transmettre est d'abord découpé en plusieurs blocs source de même taille.
45
+
- Un tirage aléatoire est ensuite effectué pour sélectionner N blocs source.
46
+
- La valeur de N est choisie selon une distribution de [Soliton](https://en.wikipedia.org/wiki/Soliton_distribution) (voir graphique ci-dessous).
47
+
- Ces N blocs source sont combinés à l’aide de l’opérateur [XOR](https://fr.wikipedia.org/wiki/Fonction_OU_exclusif) pour former un seul bloc encodé.
48
+
- Ce bloc encodé est ensuite transmis au récepteur avec un identifiant précisant le nombre de blocs source qu’il contient.
49
+
- Dans notre cas, ce bloc est transféré via un QR code, les 12 premiers octets étant réservés pour l’identifiant.
Distribution de Soliton. Notez qu'en suivant cette distribution, il y aura principalement des combinaisons de 2 blocs
65
-
et qque fois des blocs seuls, essentielle pour pouvoir faire les premiers XOR.
52
+
Distribution de Soliton utilisé pour choisir le nombre de bloc source à combiner.
53
+
Notez qu'il y aura principalement des combinaisons de 2 blocs et plus rarement des blocs seuls.
54
+
66
55
</div>
67
56
</div>
68
57
69
58
70
59
#### Recepteur
71
-
- Le recepteur collecte les paquet encodé en scannant les QR code
72
-
- Si le paquet est composé d'un bloc source il le met de coté
73
-
- Si le paquet est composé de 2 bloc source, il fera un XOR avec un des paquet déjà recu pour reconstruire le second paquet source.
74
-
- Il procède ainsi de suite avec des paquets composés de 3,4..N bloc sources.
75
-
- Lorsqu'il a reçu tout les paquets, il les remet dans l'ordre pour reconstruire le message original.
76
60
77
-
En combinant les blocs avec un XOR, cela nous permet d'envoyer statistiquement beaucoup moins de bloc que la méthode naïves
78
-
qui consisterai à les envoyer un par un.
61
+
- Le récepteur collecte les paquets encodés en scannant les QR codes.
62
+
- Si un paquet est composé d’un seul bloc source, il le stocke directement.
63
+
- Si un paquet est composé de 2 blocs source, il applique un XOR avec un des paquets déjà reçus pour reconstruire le second bloc source.
64
+
- Il poursuit de cette manière avec les paquets contenant 3, 4 ... blocs
65
+
- Une fois tous les paquets reçus et reconstruits, il les remet dans l’ordre pour reconstruire le message original.
79
66
80
-
Une implementation de cette librarie est disponnible pour python à cette adresse.
67
+
En combinant les blocs avec un XOR, on peut transmettre statistiquement beaucoup moins de blocs que la méthode naïve,
68
+
qui consisterait à les envoyer un par un.
81
69
70
+
Une implémentation de cet algorithme est disponible dans la bibliothèque [lt-code](https://github.com/anrosent/LT-code) en Python.
82
71
83
-
## Mise en place
84
72
85
-
Avec tous ces ingrédients, j'ai construit une petit librarie me permettant de transférer des données
86
-
via des QR code. Le code source est disponnible sur https://github.com/dridk/qrfontain.
73
+
## Implementation en python
87
74
88
-
### Pour emettre
75
+
Avec tous ces éléments, j'ai développé une petite librarie disponnible sur Github appelée [qrfontain](https://github.com/dridk/qrfontain/) qui permet de transférer des données via une flux de QR codes.
76
+
77
+
### Pour emettre un fichier
89
78
90
79
```python
91
80
import qrfontain
@@ -96,7 +85,7 @@ with open("big.txt", "rb") as file:
96
85
display(image)
97
86
98
87
```
99
-
### Pour recevoir
88
+
### Pour recevoir un fichier
100
89
101
90
```python
102
91
import qrfontain
@@ -109,28 +98,50 @@ with open("output.txt", "wb") as file:
109
98
110
99
```
111
100
112
-
### Recepteur
113
-
Pour le recepteur, j'ai egallement crée une petite application graphique en Qt.
114
-
J'utilise QScreen.grabWindow pour faire des screenshots et zbarlight pour la capture des qrcode.
115
-
L'application me permet de selectionner une région de mon bureau avec un carré transparent pour
116
-
capturer les QR codes et télécharger les données.
101
+
### Experience
102
+
103
+
Pour l'expérience, j'ai créé trois fichiers de tailles différentes (100 Ko, 1 Mo et 10 Mo) que j'ai encodés dans une vidéo de QR codes à 30 images par seconde.
104
+
Pour le décodage, j'ai développé une interface graphique en [Qt](https://doc.qt.io/qtforpython-6/) capable de capturer des QR codes à 60 fps. J'utilise [QScreen.grabWindow](https://doc.qt.io/qt-6/qscreen.html#grabWindow) pour prendre des captures d'écran et [zbarlight](https://github.com/Polyconseil/zbarlight) pour la détection des QR codes. L'application permet de sélectionner une région de l’écran via un carré transparent pour capturer les QR codes et récupérer les données transmises. Voir la vidéo ci-dessous. C'est assez satisfaisant, on a l'impression de récupérer un signal radio extra-terreste.
0 commit comments