Pour me familiariser avec la librairie jQuery et découvrir ses possibilités d'animation, je me suis amusé avec beaucoup de nostalgie à réaliser une grossière adaptation du célèbre jeu vidéo "Duck Hunt". Le résultat obtenu en quelques rapides lignes de code est accessible via le lien ci-dessous.
Par soucis de performance, il m'arrive de temps en temps d'exporter le contenu d'une table MySQL pour en créer un tableau PHP associatif. Disposant ainsi des données en mémoire, ceci me permet, par exemple lors d'une requête de sélection, d'épargner une jointure avec cette table. Bien entendu, ceci n'est réellement intéressant que pour les tables de petite taille (table de devises, de pays, etc...)
Malgré la petite taille de ces tables, la procédure pour générer le code du tableau est généralement fastidieuse à moins de disposer d'un petit script "fait maison" sous la main.
J'ai donc décidé de publier un modeste outil utilisable sous la forme d'un plugin pour phpMyAdmin. Il ajoute la fonctionnalité désirée (cf. checkbox "PHP Array") à la liste des formats disponibles pour l'export des bases de données.
Pour l'installation, rien de plus simple. Il suffit de télécharger le plugin ici et d'extraire le fichier PHP dans le répertoire phpMyAdmin/libraries/export/.
Par contre, le script étant toujours en version beta, tout rapport de bug ou suggestion d'amélioration sera vivement apprécié. Merci d'avance !
Intrigué par les algorithmes de compression de données, je me suis penché sur RLE qui est sans conteste l'un des moins complexe à implémenter. Il s'applique aux données qui présentent de longues répétitions d'un même caractère. Le principe consiste à ne conserver qu'un seul caractère de chaque plage auquel on préfixera le nombre réel de répétitions attendues. Par exemple :
AAAABBBBBBCDDDDDEEEEEEEEE (25 octets)devient
4A6B1C5D9E (10 octets)Dans ce cas bien choisi le niveau de compression est intéressant, mais loin d'être systématiquement satisfaisant : l'algorithme s'avère en effet très peu approprié aux données qui ne présentent pas de répétitions suffisantes. Ainsi :
ABCDE (5 octets)devient
1A1B1C1D1E (10 octets)
On voit clairement que RLE ne peut être envisagé que dans des domaines d'application bien précis pour pouvoir en espérer un quelconque bénéfice. Initialement inventé pour compresser les documents scannés en noir et blanc (qui présentent inévitablement de longues plages d'octets "blancs"), on peut l'appliquer au cas typique des images bitmaps formées de grandes zones d'une couleur unie. Ces pixels contigus dont le code couleur est identique se traduiront dans le fichier par une suite consécutive d'octets identiques.
Pour illustrer ce principe, j'ai testé la compression du fichier bitmap ci-contre. La compression RLE a permi de réduire le poids du fichier de 67.3 Ko à 9.1 Ko, c'est qui est déjà appréciable.
Ce qui laisse rêveur, c'est d'imaginer l'inventivité mise en oeuvre par le format PNG, pour arriver avec ce même fichier source à un résultat final d'à peine 400 petits octets !
Ma classe PHP
/** * "Run-length encoding" algorithm compression class * * @author Geoffray Warnants - http://www.geoffray.be/ * @version 1.0 */ class RLE { /** * Compress a string using RLE * * @param string $str * @return string */ public static function encode($str) { $encoded = ''; for ($i=0, $l=strlen($str), $cpt=0; $i<$l; $i++) { if ($i+1<$l && $str[$i]==$str[$i+1] && $cpt<255) { $cpt++; } else { $encoded .= chr($cpt).$str[$i]; $cpt = 0; } } return $encoded; } /** * Uncompress a RLE string * * @param string $str * @return string */ public static function decode($str) { $decoded = ''; for ($i=0,$l = strlen($str); $i<$l; $i+=2) { if ($i+1<$l && ord($str[$i]) > 0) { $decoded .= str_repeat($str[$i+1], 1+ord($str[$i])); } else { $decoded .= $str[$i+1]; } } return $decoded; } }
Avec quelques jours de retard, je viens de tester les améliorations mineures apportées par la toute fraiche release 5.2.9 de PHP, dernière ligne droite avant la très attendue 5.3. Outre les corrections de plusieurs bugs, cette nouvelle version présente une légère amélioration du comportement de la méthode magique __call() vis à vis des méthodes privées et protégées. Ainsi, sous les versions antérieures à 5.2.9, l'exemple suivant se soldait par une toute belle Fatal error: Call to private method Foo::bar() from context ''
<?php class Foo { public function __call($method, $args) { if (method_exists($this, $method)) { call_user_func_array(array($this, $method), $args); } } private function bar() { echo 'Hello'; } } $foo = new Foo(); $foo->bar(); ?>
Bonne nouvelle : cet agaçant comportement que tout un chacun a probablement déjà rencontré fait désormais partie du passé.
A l'école primaire, il m'arrivait souvent de jouer les agents secrets en mettant mes camarades au défi de déchiffrer des messages codés. Un codage utilisé était par exemple de remplacer chacune des lettres par sa précédente dans l'alphabet, rendant ainsi le texte illisible mais facilement déchiffrable par qui en connaissait l'astuce.
Sans le savoir, je venais de mettre en pratique une méthode de chiffrement ancestrale appelée le Chiffre de César en l'honneur à Jules César, son inventeur, qui l'utilisait probablement en son temps pour transmettre ses mots doux en toute discrétion ;-). Un cas particulier de cet algorithme est le ROT13, qui décale chaque caractère alphabétique de 13 positions. Une clé qui n'a pas été choisie sans raison : Considérant notre alphabet de 26 lettres comme une suite circulaire (on revient au A après le Z), appliquer la translation 2 fois de suite permet de retrouver le texte original.
C'est d'ailleurs pourquoi la fonction PHP str_rot13() ne possède tout logiquement pas d'équivalence pour le décodage.
echo str_rot13(str_rot13('La boucle est bouclée'));Je trouve cet exemple très pertinent pour illustrer que le fait d'appliquer successivement une même fonction d'encodage contribue parfois à affaiblir la robustesse d'un algorithme !