Défi n°6 : Le coté obscur de EVAL
Venez relever les défis MATLAB.
Le 2012-10-08 15:26:05, par Jerome Briot, Rédacteur/Modérateur
Voici deux lignes de code MATLAB que vous pouvez exécuter sans aucun risque, faites moi confiance
Code : |
1 2 3 | str = 'eval(sprintf(''%c'',99,108,99)),eval([''f'' 112 114 105 110 116 102 40 39 37 99 39 44 91 56 32 49 48 32 49 48 32 49 48 32 49 48 32 53 32 57 32 49 48 32 49 48 32 49 48 32 49 48 93 46 94 50 43 91 56 32 49 32 56 32 56 32 49 49 32 55 32 54 32 49 49 32 49 52 32 56 32 48 93 44 114 101 112 109 97 116 40 56 44 49 44 49 49 41 41]);'; eval(str) |
Ou du moins qu'il ne semble rien faire, et pourtant ce code effectue bien 3 actions distinctes
Saurez-vous trouver ce que font les 3 actions cachées dans ce code
---------------------------------------------------
---------------------------------------------------
A votre logique et à vos claviers !
-
Jerome BriotRédacteur/Modérateurle 08/10/2012 à 21:17
-
Jerome BriotRédacteur/ModérateurVoici la réponse
-------------------------
La fonction EVAL exécute l'action qui lui est passée sous forme de chaînes de caractères.
Ici, la chaine de caractères str contient elle-même deux appels à EVAL dont les contenus sont codés.
La première chaine de caractères est
Code : 'eval(sprintf(''%c'',99,108,99))'
Code : eval(sprintf('%c',99,108,99))
Dans ce cas, MATLAB utilise la table ASCII pour faire la conversion "nombre" => "caractère"
Code : 1
2
3
4
5>> sprintf('%c',99,108,99) ans = clc
Code : eval('clc')
En suivant le même raisonnement pour le second appel à EVAL, on obtient :Code : eval(['f' 112 114 105 110 116 102 40 39 37 99 39 44 91 56 32 49 48 32 49 48 32 49 48 32 49 48 32 53 32 57 32 49 48 32 49 48 32 49 48 32 49 48 93 46 94 50 43 91 56 32 49 32 56 32 56 32 49 49 32 55 32 54 32 49 49 32 49 52 32 56 32 48 93 44 114 101 112 109 97 116 40 56 44 49 44 49 49 41 41])
Code : 1
2
3
4
5>> ['f' 112 114 105 110 116 102 40 39 37 99 39 44 91 56 32 49 48 32 49 48 32 49 48 32 49 48 32 53 32 57 32 49 48 32 49 48 32 49 48 32 49 48 93 46 94 50 43 91 56 32 49 32 56 32 56 32 49 49 32 55 32 54 32 49 49 32 49 52 32 56 32 48 93 44 114 101 112 109 97 116 40 56 44 49 44 49 49 41 41] ans = fprintf('%c',[8 10 10 10 10 5 9 10 10 10 10].^2+[8 1 8 8 11 7 6 11 14 8 0],repmat(8,1,11))
Code : 1
2
3
4
5>> [8 10 10 10 10 5 9 10 10 10 10].^2+[8 1 8 8 11 7 6 11 14 8 0] ans = 72 101 108 108 111 32 87 111 114 108 100
Code : 1
2
3
4
5>> char([72 101 108 108 111 32 87 111 114 108 100]) ans = Hello World
La seconde chaine de caractère donne :Code : 1
2
3
4
5>> repmat(8,1,11) ans = 8 8 8 8 8 8 8 8 8 8 8
En se référant à la table ASCII, on voit que la valeur 8 correspond au caractère Backspace qui efface le caractère qui le précède.
FPRINTF efface donc les 11 derniers caractères qu'il vient d'afficher.
Comme la chaîne "Hello World" fait exactement 11 caractères, elle est effacée !
-------------------------
Donc, pour résumer :
1) Nettoyage du Command Window avec CLC
2) Affichage de "Hello World" avec FPRINTF
3) Effacement de "Hello World" grâce au caractère Backspace
Donc au final, l'utilisateur à l'impression que le code ne fait rien, ce qui est faux.
-------------------------
Ce défi permet de mettre en évidence le coté peu lisible d'un code qui utilise EVAL.
Il est toujours préférable de trouver des alternatives à son utilisation.
=> Comment créer des variables nommées A1, A2, A3, ..., AN ?
D'autre part, la technique du backspace vous permet de créer un compteur rapide et compact dans le Command Window.
Ceci peut être une alternative efficace à la fonction WAITBAR
=> Afficher une barre de progression de l’exécution
-------------------------le 22/10/2012 à 9:14