Développement web et musiques électroniques

bcolin

Over-blog, Citroulette et les iframes

Je ne vais pas vous re-présenter Citroulette, ce drôle de petit site que j'ai lancé il y a quelques jours (voir ici), ni vous ennuyer avec les multiples petits ajustements que je viens d'y faire (traduction en Français, système de tirage au sort "intelligent" afin de pas revoir un site déjà vu, favicon, modèle publicitaire qui a changé...)

J'ai par contre un problème technique politique technico-politique. Citroulette affiche les sites web grâce l'utilisation d'iframes. Une iframe, c'est un genre de fenêtre dans laquelle on peut afficher une autre page web. Donc, grâce à cette technique, n'importe quel site web peut afficher le contenu d'un autre site web.

Et comme toujours dans le monde du web, cette capacité d'inclusion d'une page dans une autre a été l'objet d'abus de la part de webmasters douteux. Quoi de plus simple que de proposer du contenu qui n'est pas le sien, tout en positionnant sa publicité autour de l'iframe...

Ainsi, il y a des sites web qui refusent d'être affichés dans une iframe. Cela peut être via un refus explicite du webmaster (c'est pour cela que je demande toujours avant d'ajouter un site dans Citroulette), ou, plus simplement, un petit bout de javascript qui détecte que le site est affiché dans une iframe, et qui force l'ouverture du site par-dessus l'iframe, par exemple.

if (parent.frames.length > 0) {
    top.location.replace(document.location);
}

Ceci est le choix fait par over-blog : impossible d'afficher un over-blog dans une iframe. En conséquence, tant que je n'ai pas trouvé de parade technique, je ne peux pas ajouter d'over-blogs dans la Citroulette. Ça fait mal, car over-blog est la troisième plateforme de blogs, du moins d'après cet article.

J'ai donc passé beaucoup de temps à essayer de contrer techniquement cette redirection. Dans le monde web, c'est une problématique bien connue (voir ici ou ici), et j'ai tenté pas mal de techniques à base de onbeforeunload et d'écouteur d'évènements en tout genre, sans succès pour l'instant.

Je comprend parfaitement que cette plateforme refuse de se faire "inclure" dans une iframe, c'est leur droit. Mais ce serait quand même mieux qu'over-blog laisse le choix au blogueur, via un paramètre dans l'administration du blog. (Peut-être existe-t-il déjà, ce paramètre ? Si quelqu'un sait quelque-chose là-dessus, qu'il s'exprime maintenant où se taise à jamais.)

Bref, je n'ai pas vraiment envie de m'engager dans un script anti-anti-iframe voire anti-anti-anti-anti-iframe (et je suis sérieux ! Ça peut aller très loin). Je continue à creuser cette problématique, mais déjà, j'en appelle à over-blog de permettre à ses blogueurs, s'ils le souhaitent, que leur blog soit affiché dans une iframe.

En attendant, chaque site soumis dans Citroulette passe préalablement par cette page de test très simple, et si le site ne se laisse pas inclure, j'envoie un mail au proprio expliquant le problème.

Bien dommage tout ça. Affaire à suivre !



8 Commentaires

Je lance Citroulette.com. Servez-vous tant que c'est chaud !

Citroulette

Clic, clic, clic... En ce moment on dirait que le "Next" est à la mode. Alors je lance Citroulette, au concept très simple et très con : un gros bouton rouge qui permet de naviguer au hasard de site en site, nonchalamment.

Franchement, si je parviens à proposer surtout des sites sympa dans cette roulette, je trouve que ça peut être un moyen de surfer assez distrayante !

Pour l'instant, citroulette ne comporte que mon site à moi, plus quelques blogs que je suis régulièrement par RSS, à qui j'ai demandé l'autorisation. Ajoute ton site à la citroulette ! Il y a une petite fonction "Add your website" sur la page.

Comme il y aura très peu de sites dans citroulette les premiers jours de son lancement, ton site sera souvent tiré au hasard, l'apport de trafic pourrait être important. C'est maintenant que ça se joue, cousin !

Voilà, sinon peut-être aura-tu remarqué que le blog à été redesigné, qu'il change légerement d'adresse (http://bcolin.com --> http://blog.bcolin.com), et que désormais je m'appelle Miniloop au niveau musical avec aussi un nouveau design.

Have fun with Citroulette !

j'aime bien le concept :)
FOx15 - site
bien vu.
Gaëtan


8 Commentaires

Pourquoi doit-on compter en commençant à 0 en programmation ?

Supposons que vous deviez écrire, en programmant, une boucle qui doit itérer 10 fois.

Hébin, il y a au moins ces deux façons de l'écrire :

  • for (i = 0; i < 10; i++)
  • for (i = 1; i <= 10; i++)

Soit on démarre de 0 et on s'arrête à 9, soit on démarre de 1 et on s'arrête à 10.

On sait que, d'un point de vue humain, la deuxième solution est plus facilement compréhensible.

On sait tous, aussi, que d'un point de vue développement, c'est la première solution qu'il faut utiliser. (Nota : ça dépend aussi du language de programmation, hein).

Oui mais le pourquoi, bordel ? Vous ne vous être jamais demandé pourquoi il fallait compter en commençant à 0 en programmation ?

Voici une réponse à ce pourquoi. Je suis tombé je sais plus comment sur cette petite démonstration du professeur Edsger W. Dijkstra, que je vous traduis.


Supposons que nous devions décrire qu'un nombre X est compris entre 2 (inclu) et 12 (inclu). Il y a quatre conventions pour écrire cela :

  • (A)   2 ≤ x < 13
  • (B)   1 < x ≤ 12
  • (C)   2 ≤ x ≤ 12
  • (D)   1 < x < 13

Examinons-les pour voir laquelle serait la meilleure.

Dans la suite d'entiers 2 .. 12, il y a 11 élèments (et non pas 10).

Les conventions (A) et (B) ont un premier avantage : La différence entre les bornes supérieures et inférieur est égale à la longueur de la suite. 13 - 2 = 11 et 12 - 1 = 11.

Autre avantage des conventions (A) et (B) : elle se comportent bien lorsque on souhaite "coller" deux suites de chiffres. Soit les deux suites :

  • 2 ≤ x < 5
  • 5 ≤ x < 12

On remarque que le chiffre de la borne supérieure de la première est égale à celui de la borne inférieure de la deuxième, ce qui est bien plus confortable pour travailler.

Ces observations étant faites, comment trancher entre les conventions (A) et (B) ?

La solution (B) présente un gros défaut : pour trouver le plus petit élèment de la suite, on doit effectuer un "calcul" : trouver le plus petit entier naturel strictement plus grand que 1. C'est moche.

En conclusion, la convention (A) semble être la meilleure pour décrire une suite de chiffres.


Donc, programmatiquemment parlant, si je dois effectuer une boucle qui doit itérer 11 fois, la bonne synthaxe est :

for (i = 0; i < 11; i++)

Ainsi, je vois tout de suite d'où je pars (0), je vois tout de suite que je vais itérer 11 fois, et si je dois créer une suite adjacente, je la démarrerais de 11.

Rhô, c'est beau.



2 Commentaires

Trucs et astuces du développeur - boulet

  1. Cassez toutes convention de codage. N'utilisez pas deux fois la même casse : mafonction(), Ma_Fonction(), MAFONCTION(). N'indentez pas votre code. La limite de 80 caractères par ligne de code, c'est pour les petits joueurs. Soyez-vous même, créez votre style !

  2. Commenter son code ? C'est pour les loosers. Le vrai beau code parle de lui-même. Mais veiller à toujours laisser un commentaire d'en-tête avec votre nom et votre mail, pour recevoir les offres d'emploi et courriers admiratifs de ceux qui reprendront votre code.

  3. Un développeur expérimenté est supposé savoir réutiliser un code existant. Montrez votre art en la matière : copier et collez le premier code d'exemple qui apparait quand on appuie sur le bouton "J'ai de la chance" de Google. Le modifier le moins possible : nous savons tous que les exemples données sur les forums de discussions ont été préalablement validés par des professionnels.
  4. Ne pas perdre de temps sur l'optimisation et la consommation de ressources. Les ordinateurs sont tellement puissants de nos jours...

  5. Vérifiez la complexité cyclomatique de votre code. Plus elle est élevée, plus vous serez considéré comme élégant et ingénieux. Un score de 25 est un minimum.

  6. Le travail en équipe projet est une compétition. Assurez-vous d'envoyer votre mises à jour de code AVANT que vos collègues le fassent. Rentrez ensuite immédiatement chez vous et savourez votre victoire, les perdants n'ont plus qu'à rester tard pour résoudre les conflits que vous avez engendré.

  7. Laissez à ceux qui reprendront votre code de petites dédicaces encourageantes.
5687:                END IF;  -- You can now hang yourself here.
5688:              END LOOP;  --                               |
5689:            END IF;      --                               |
5690:          END IF;        --                               O
5691:        END IF;          --                              /|\
5692:      END LOOP;          --                              / \
5693:    END IF;
5694:  END IF;
5695:END;

Source : Je sais plus trop comment je suis arrivé sur ce petit blog de 10 billets, dernière mise à jour : avril 2008... mais certains articles m'ont beaucoup parlé, notamment celui-ci dont je vous livre les morceaux choisis et traduits.

Tellement vrai.
Laviemobile - site


4 Commentaires

Je vous présente en exclusivité les minicoms pour blogs ! (Facebook style)

L'idée est venue, vous aurez deviné, en me baladant sur Facebook. J'ai trouvé sympa le fait de pouvoir approuver rapidement (en un seul clic) un post d'un ami, sans autre commentaire.

Pourquoi ne pas porter cette bonne idée sur un blog ?

J'ai donc enrichi très légérement le concept avec d'autres expressions (bof, hahaha, etc... :) et donné la possibilité de laisser facultativement un petit commentaire.

Ainsi, le visiteur qui veut montrer qu'il a apprécié un article mais qui n'a pas de commentaire particulier à faire n'est pas obligé de se manger un "super article, merci !". Un petit clic et puis voilà.

C'est finalement une façon discrète de montrer qu'on est passé, qu'on a lu et qu'on a bien aimé / pas aimé / rigolé / etc.

J'ai donc baptisé ce système "Minicoms" et je suis heureux de pouvoir les proposer sur ce blog ! Le temps dira si cette alternative (ou plutôt, ce complément) aux commentaires classiques est pertinente...

PS : Pour ceux qui auront noté, un peu de redesign a été fait... ajout d'un lien "page au hasard" et enjolivage des commentaires classiques, entre autres !

Benoit
pour voir
Essai - site
Trop cool comme blog !
djmakina - site
ca a l'air rigolo
Yann
Excellente idée.
Laviemobile - site
Simon - site
Lolo
oui je veux tester
oursenpluche
Idée très utile... Bravo!
Gipi - site


17 Commentaires

Wolfram : le moteur de recherche qui comprend vraiment votre requête

Présenté il y a quelques temps comme un Google-killer, le moteur de recherche Wolfram est maintenant accessible en version alpha. C'est un truc de dingue, mais vraiment.

Contrairement à Google, Wolfram ne présente pas de liste de pages web correspondant à notre requête... Wolfram nous calcule la réponse à notre requête !

C'est très impressionnant. Pour réaliser cela, ils ont réunis et structurés plus de 10 milliard de données brutes en tous genres, créés 50 000 modèles et algorithmes pour plus de 1000 domaines de connaissance : maths et physique, bien sûr, mais aussi la culture, l'histoire, la science de la vie, chimie, sport, musique... Et pour faire tourner tout ça, des fermes de superordinateurs qui font tourner un noyau de 5 millions de lignes de code Mathematica.

Le résultat ? Hé bien, vous pouvez lui demander, en language courant, le temps que vous prendrait une chûte de 1km (16,8 secondes !), quand est-ce que la musique "Like a Rolling Stone" est sortie, de comparer la population féminine et masculine au Japon, le volume sonore perçu par un humain d'un son de 60 dB à 110Hz... et même l'âge de Madonna, hé oui. (Attention hein, je suis pas fan du tout :)

Tout est possible ! Je suis sûr que si ce moteur s'étoffe avec encore plus de données, il deviendra bientôt un incontournable du web.

Complétement dingue. Allez voir les exemples, vous n'en reviendrez pas.

PS : Ca m'a permi aussi d'apprendre que le Wolfram et le Tungstène, c'est pareil.

PS 2 : rhô, il y a même un whois de domaine !



2 Commentaires

Back-office de cybergang

Un des plus grand réseau d'ordinateurs zombies a été mis à jour par Finjan, un éditeur de sécurité, qui a découvert que pas moins de 1,9 millions de PC zombies sont contrôlés à distance par ce cybergang. Ouch.

Quand on cherche à contrôler ainsi une telle quantité de machines, des outils sont nécessaires pour y arriver. Il faut notamment un serveur, qui connait l'adresse de tous ces ordinateurs infectés et qui peut leur envoyer des ordres (télécharge tel fichier sur telle url, exécute silencieusement tel fichier, etc.)

Sur un tel serveur, des petits programmes (souvent faits maisons) sont utilisés par les hackeurs. De façon plus ou moins automatique, ce sont ces programmes qui gèrent l'intelligence du réseau de PC zombies, et qui peuvent déclencher de véritables bombes virtuelles par un simple clic sur un bouton.

Ce qui est intéressant ici, c'est que la firme à réussi à mettre la main sur ce serveur - situé en Ukraine - et plus fort encore, à accéder à cette fameuse application qui gère ces PC zombies...

Et cette application est "sympa" ! Les screenshot ci-dessous montrent une interface ergonomique et confortable à utiliser. C'est un véritable back-office pour hackeurs, loin des petits bricolages courants dans ce milieu. Alors, à quoi ressemble une interface d'administration de PC zombies ? Place aux screenshots :

Sur celui-ci, on peut voir un début de la liste des ordinateurs infectés et le nombre total d'ordinateurs infectés. Les gars de chez Finjan disent voir ce nombre augmenter d'heure en heure, en direct.





Ici, on peut voir une interface permettant d'éditer une commande malicieuse, du genre "Télécharge un fichier sur telle url". Cette même commande pourra être envoyée à tous les PC infectés. Notez la présence de boutons "Rule Code" et "Condition code" qui laissent deviner que la commande pourra varier selon des critères (version de Windows, antivirus etc.)



Ces différentes commandes malicieuses sont ici listées. D'un simple clic, on peut demander au serveur de les transmettre aux PC infectés.

Les pirates sont ainsi capables de faire à peu prêt ce qu'ils veulent sur les PC infectés :

  • Lire l'adresse mail et autres infos de l'utilisateur
  • Faire communiquer l'ordinateur avec d'autres
  • Lancer un programme sur le PC
  • Injecter du code dans d'autres programmes
  • Faire visiter des sites web
  • Ecouter les entrées clavier...

Avec une telle force de frappe, ce cybergang peut faire tomber la plupart des services disponibles sur le web, et donc faire du chantage, et donc se renforcer...

Via Finjan vital security



2 Commentaires

8 expérimentations Javascript pouvant être utiles sur un blog

Voici une petite sélection d'expériences Javascript qui ont retenu mon intérêt. Je pense bientôt en essayer quelque-unes, en gardant en tête de laisser le code clean et de ne pas flinguer l'accessibilité (flux rss, navigateur sans javascript etc.)



5 Commentaires

Pwn2Own Contest : Tous les navigateurs crackés, sauf Chrome, mais ça ne veut rien dire

Des professionnels qui s'acharnent à prendre le contrôle d'une machine à partir d'une faille de navigateur : tel est le contexte du Pwn2Own Context, en mars dernier, au Canada.

Attention, ces pros de la faille ne débarquent pas les mains vides. La plupart ont déjà sous le coude leur programmes, pages web, morceau de flash ou javascript qu'ils améliorent continuellement et protégent jalousement des regards.


Charlie Miller (à gauche) et Nils (à droite) (Credit: TippingPoint DVLabs)

En effet, ces hackeurs que l'on pourrait assimiler à des chercheurs en sécurité, peuvent tirer de ces failles une gloire personnelle ou une rémunération. Tout dépend du contexte dans lequel ils dévoilent leur méthode de hack.

Par exemple, une faille découverte sur un navigateur peu répandu (Opéra, Chrome) sera faiblement monétisé. Mais si la faille est une simple page web, ou un petit morceau de javascript bien ficellé, elle peut faire couler beaucoup d'encre et donner un coup de projecteur sur le hacker. Mais c'est tout.

Par contre, une faille découverte sur un navigateur très répandu (Internet Explorer) attirera plus l'attention et pourra être vendue beaucoup plus chère (plusieurs dizaines de milliers de dollars).

Ainsi, selon le navigateur, l'enjeu pécunier n'est pas le même. D'ailleurs le concours Pwn2Own n'offre aucune somme pour des failles découvertes sur Opéra ! Ce navigateur (pourtant répandu dans le monde mobile) est donc délaissé par les hackeurs... et dans une moindre mesure, Chrome aussi. Les hackeurs qui recherchent l'argent (les plus nombreux) se concentrent sur IE et Firefox...

Alors, quid du résultat du Pwn2Own Contest ? Tous les navigateurs ont pu être crackés, sauf Chrome ? Oui, c'est une info, mais ne généralisons pas. Ceci n'est pas un test de sécurité des navigateurs.

C'est juste une bande de gars talentueux qui s'archarnent sur quelques navigateurs dont ils ont la prédilection. Ne réduisons pas la notion de sécurité des utilisateurs, beaucoup plus complexe, au résultat de ce genre de concours.



1 Commentaires

Bloggeurs, bloggeuses, mettez vos liens de commentaires en DoFollow

Vous n'avez rien compris au titre ? Explications. Vous possédez un blog. Sur celui-ci, vos visiteurs peuvent laisser des commentaires. Si un de vos visiteur possède aussi un site web, il peut l'indiquer dans son commentaire. Une fois le commentaire enregistré, ce lien apparaît sur votre blog. Les personnes qui visitent votre site peuvent éventuellement cliquer dessus pour aller faire un tour sur le site du commentateur.

Arrive ensuite notre ami Google... Du point de vue de Google, lorsque votre site fait un lien vers un site extérieur, cela équivaut à ce que votre site vote pour ce site extérieur. Plus un site a été voté, plus son pagerank sera élevé et plus il apparaîtra haut dans les résultats de recherche.

L'objectif des professionnels du référencement est donc d'obtenir un maximum de liens vers leur site. Et pour cela, les commentaires de blogs sont une solution idéale !

C'est ainsi que s'est développé le spam de blog... Des robots donc, qui balancent à tout va des commentaires bidons qui comportent toujours un ou plusieurs liens vers un site dont ils veulent promouvoir le classement. Si vous avez envie d'en savoir plus sur les personnes qui créent ces programme, je vous propose cette interview chez Pagasa.

Ces spams de blogs constituent un vrai poison car ils biaisent les résultats de vos recherches. Pour pallier à cela, les plateformes comme Wordpress ou Blogger ont choisi d'afficher, par défaut, les liens de vos commentateurs avec un attribut spécial dédié aux moteurs de recherche : le NoFollow. Il indique tout simplement aux moteurs de recherche de ne pas interpréter ce lien comme étant un vote.

Cette règle s'est donc mis en place sur nos blogs depuis quelques temps.

Alors ?

Hé bien avec le recul, on se rend compte que ça ne rend pas justice à ceux qui laissent des commentaires. Les visiteurs actifs, qui prennent le temps de lire votre blog (c'est cool) et qui en plus se fendent d'un commentaire (c'est encore plus cool) méritent un peu plus de considération de la part de votre site, et présenter un lien en dur vers leur site est une forme de rétribution que vous pouvez choisir de donner.

De plus, aujourd'hui, avec les capcha et autres systèmes anti-spam-de-blog, vous limitez fortement l'arrivée de spam sur votre blog, ainsi vous pouvez à la fois offrir des liens en dur tout en ayant la bonne conscience de ne pas faire la promo de sites douteux.

Alors, prêt pour le DoFollow ? Il ne vous reste plus qu'à vous renseigner sur le site officiel du DoFollow. Pleins d'infos intéressantes aussi chez Blogmotion.

Pour ma part :

  • Tous mes liens sont en DoFollow (pas besoin de plug-ins ou autre manips, ce moteur de blog est codé maison ;) et ce depuis le début... car c'est aussi une façon de dire à mes visiteurs qu'ici, c'est PAS tout pour ma gueule et rien pour les autres.

  • Pas besoin de capcha ici. Mon système de commentaire en fenêtre flottante ne peut pas être "compris" par les spambots. Contrairement à mon ancien système classique, je n'ai jamais reçu aucun spam depuis la mise en place.

  • Enfin, les liens affichés ne s'ouvrent PAS dans une nouvelle fenêtre. C'est au visiteur de décider, pas à moi. Une bonne pratique que j'aimerais voir plus souvent...

No-NoFollow/Dofollow



13 Commentaires

Quelques travaux sur l'ergonomie du blog

Hop, mise à jour du site !

Passage sur 2 colonnes, simplification du look général. Mais surtout quelques modifications, qui sont aussi des propositions pour améliorer la navigation sur un blog :

  • Des boutons "5 Suivants" et "5 Précédents" en bas de page. Ce qui permet de parcourir par liste de billets. Mais si on survole le bouton, une liste apparait et permet de choisir individuellement un billet.
  • Pour naviguer plus facilement, j'ai développé un menu simple (le bloc à navigation droite) qui donne les derniers articles, les articles les plus commentés et les derniers commentaires, avec un coup d'ajax pour que ça aille vite !
  • Enfin, il y a toujours les commentaires en fenêtre flottante sur lesquel j'ai fait quelques modifs transparentes.

L'objectif, c'est d'avoir des fonctions de navigation rapides et intuitifs, mais sans occuper trop d'espace afin de bien laisser la place au contenu.



3 Commentaires

Positionnez facilement et rapidement vos multiples fenêtres

C'est très courant chez moi : j'ai toujours plein de fenêtres ouvertes en même temps. Et au boulot, c'est encore pire, j'ai dû doubler la hauteur de ma barre des tâches pour pouvoir me repérer correctement entre toutes mes applications.

Il m'arrive souvent d'avoir besoin de voir simultanément plusieurs fenêtres, ici une fenêtre de code, ici une console de commande, ici un site web... mais qu'est-ce-que c'est pénible de les positionner et redimensionner afin d'avoir une occupation de l'écran qui soit confortable !

Il y a bien les fonctions de "mosaïque horizontale" et "verticale" de windows, accessibles par un clic droit sur la barre des tâches, mais cela ne me convient pas : ça s'applique qu'aux fenêtres ouvertes, on ne peut pas faire certaines combinaisons (par exemple, une fenêtre occupe la moitié gauche, deux autres fenêtres sur un quart d'écran à droite...), et en plus ma barre des tâche est tellement blindée que j'ai du mal à trouver un coin de libre pour faire un clic droit.

Du plus, j'ai souvent besoin de pouvoir mettre rapidement une fenêtre en mode "toujours devant" (always on top), mais non, pas de fonction native sous windows pour le faire.

Alors, j'ai le plaisir de vous présenter un petit programme fait maison, que j'utilise depuis quelque temps et dont je ne pourrais plus me passer !

Voici QuickArrange, un arrangeur de fenêtres dont le but est d'être simple, rapide et fonctionnel :)

Un simple CTRL + CLIC DROIT ouvre un menu permettant de :

  • Positionner une fenêtre sur la moitié gauche ou droite de l'écran
  • Positionner une fenêtre sur l'un des quatre quarts de l'écran
  • Mettre une fenêtre en mode "Toujours devant", ou pas
  • Tout minimiser ou tout maximiser

Il ne nécessite aucune installation (il suffit de lancer le .exe)

Testé sur mon poste sous Windows XP SP3... aucune idée de ce que ça donne sous Vista !

C'est la version 1.0... Idées d'amélioration, correction de bug, etc ? Je suis à votre écoute !



3 Commentaires

Difficile à croire, mais ça COMPILE

Chaque année à lieu le Concours International du Code C Obscur - The International Obfuscated C Code Contest. L'objectif ?

  • Ecrire un programme C le plus obscur possible. (il y a quand même des règles à respecter)
  • Montrer l'importance du style dans la programmation, de façon ironique
  • De mettre les compilateurs C à l'épreuve avec du code tordu
  • D'illustrer quelques subtilités du langage C

Inutile de précisier qu'ils ont un humour qui fait mouche chez moi...

Voici quelques morceaux choisis. Oui, ça compile, et oui, ces programmes remplissent une fonction !


This program takes a single command line argument, transcribes the argument text into Tolkien's Elvish letters, and writes the transcription to standard output as a portable graymap (PGM) file.

                                  #include\
                                  
                     #include                
                     #include                

                    #define w "Hk~HdA=Jk|Jk~LSyL[{M[wMcxNksNss:"
                   #define r"Ht@H|@=HdJHtJHdYHtY:HtFHtF=JDBIl"\
                  "DJTEJDFIlMIlM:HdMHdM=I|KIlMJTOJDOIlWITY:8Y"
                 #define S"IT@I\\@=HdHHtGH|KILJJDIJDH:H|KID"\
                "K=HdQHtPH|TIDRJDRJDQ:JC?JK?=JDRJLRI|UItU:8T"
               #define _(i,j)L[i=2*T[j,O[i=O[j-R[j,T[i=2*\
              R[j-5*T[j+4*O[j-L[j,R[i=3*T[j-R[j-3*O[j+L[j,
             #define t"IS?I\\@=HdGHtGIDJILIJDIItHJTFJDF:8J"

    #define y                  yy(4),yy(5),                yy(6),yy(7)
  #define yy(              i)R[i]=T[i],T[i ]            =O[i],O[i]=L [i]
#define Y _(0          ], 4] )_ (1 ], 5] )_ (2      ], 6] )_ (3 ], 7] )_=1
#define v(i)(      (( R[ i ] * _ + T [ i ]) * _ + O [ i ]) * _ + L [ i ]) *2
double b = 32  ,l ,k ,o ,B ,_ ; int Q , s , V , R [8 ], T[ 8] ,O [8 ], L[ 8] ;
#define q( Q,R ) R= *X ++ % 64 *8 ,R |= *X /8 &7 ,Q=*X++%8,Q=Q*64+*X++%64-256,
# define  p      "G\\QG\\P=GLPGTPGdMGdNGtOGlOG"   "dSGdRGDPGLPG\\LG\\LHtGHtH:"
#  define W         "Hs?H{?=HdGH|FI\\II\\GJlHJ"    "lFL\\DLTCMlAM\\@Ns}Nk|:8G"
# define   U           "EDGEDH=EtCElDH{~H|AJk}"       "Jk?LSzL[|M[wMcxNksNst:"
#  define u                  "Hs?H|@=HdFHtEI"             "\\HI\\FJLHJTD:8H"
char  *   x                   ,*X , ( * i )[               640],z[3]="4_",
*Z = "4,8O4.8O4G" r U "4M"u S"4R"u t"4S8CHdDH|E=HtAIDAIt@IlAJTCJDCIlKI\\K:8K"U
 "4TDdWDdW=D\\UD\\VF\\FFdHGtCGtEIDBIDDIlBIdDJT@JLC:8D"t"4UGDNG\\L=GDJGLKHL\
FHLGHtEHtE:"p"4ZFDTFLT=G|EGlHITBH|DIlDIdE:HtMH|M=JDBJLDKLAKDALDFKtFKdMK\
\\LJTOJ\\NJTMJTM:8M4aGtFGlG=G|HG|H:G\\IG\\J=G|IG|I:GdKGlL=G|JG|J:4b"W
S"4d"W t t"4g"r w"4iGlIGlK=G|JG|J:4kHl@Ht@=HdDHtCHdPH|P:HdDHdD=It\
BIlDJTEJDFIdNI\\N:8N"w"4lID@IL@=HlIH|FHlPH|NHt^H|^:H|MH|N=J\\D\
J\\GK\\OKTOKDXJtXItZI|YIlWI|V:8^4mHLGH\\G=HLVH\\V:4n" u t t
"4p"W"IT@I\\@=HdHHtGIDKILIJLGJLG:JK?JK?=JDGJLGI|MJDL:8M4\
rHt@H|@=HtDH|BJdLJTH:ITEI\\E=ILPILNNtCNlB:8N4t"W t"4u"
p"4zI[?Il@=HlHH|HIDLILIJDII|HKDAJ|A:JtCJtC=JdLJtJL\
THLdFNk|Nc|\
:8K"; main (
int C,char**        A) {for(x=A[1],i=calloc(strlen(x)+2,163840);
C-1;C<3?Q=_=       0,(z[1]=*x++)?((*x++==104?z[1]^=32:--x), X =
strstr(Z,z))      &&(X+=C++):(printf("P2 %d 320 4 ",V=b/2+32),
V*=2,s=Q=0,C     =4):C<4?Q-->0?i[(int)((l+=o)+b)][(int)(k+=B)
]=1:_?_-=.5/    256,o=(v(2)-(l=v(0)))/(Q=16),B=(v(3)-(k=v(1)
))/Q:*X>60?y   ,q(L[4],L[5])q(L[6],L[7])*X-61||(++X,y,y,y),
Y:*X>57?++X,  y,Y:*X >54?++X,b+=*X++%64*4:--C:printf("%d "
,i[Q][s]+i[Q ][s+1]+i[Q+1][s]+i[Q+1][s+1])&&(Q+=2)


This program accepts ASCII formatted mazes as input, and renders them onscreen for the user to explore, complete with Line Of Sight - you cannot see parts of the maze your avatar could not have seen.

#include /*****************************************************/
            int               m[256                   ] [         256   ],a
 ,b   ;;;   ;;;   WINDOW*w;   char*l=""   "\176qxl"   "q"   "q"   "k"   "w\
xm"   "x"   "t"         "j"         "v"         "u"         "n"         ,Q[
 ]=   "Z"   "pt!ftd`"   "qdc!`eu"   "dq!$c!nnwf"/**   ***   */"t\040\t";c(
int   u ,         int         v){                     v?m   [u]         [v-
 1]   |=2,m[u][v-1] &   48?W][v-1   ] &   15]]):0:0;u?m[u   -1][v]|=1   ,m[
 u-               1][   v]&         48?               W-1   ][v         ]&
15]   ]):0:0;v<   255   ?m[   u][v+1]|=8,m[u][v+1]&   48?   W][   v+1]&15]]
):0         :0;         u <               255   ?m[   u+1         ][v   ]|=
4,m[u+1][   v]&48?W+1][v]&15]]):0:0;W][   v]&   15]   ]);}cu(char*q){   return
 *q               ?cu   (q+         1)&         1?q   [0]               ++:
q[0   ]--   :1;   }d(   int   u ,   int/**/v,   int/**/x,   int   y){   int
Y=y   -v,   X=x         -u;   int         S,s   ;Y<         0?Y   =-Y   ,s,
s=-   1:(   s=1);X<0?X=-X,S   =-1  :(S=   1);   Y<<=   1;X<<=1;   if(X>Y){
int   f=Y               -(X   >>1   );;               while(u!=         x){
f>=   0?v+=s,f-=X:0;u   +=S   ;f+=   Y;m[u][v]|=32;mvwaddch(w,v   ,u,   m[u
 ][               v]&   64?   60:         46)         ;if         (m[   u][
v]&16){c(u,v);;   ;;;   ;;;   return;}}   }else{int   f=X   -(Y>>1);;   while
 (v   !=y         ){f   >=0         ?u   +=S,               f-=         Y:0
 ;v   +=s   ;f+=X;m[u][v]|=   32;mvwaddch(w,v   ,u,m[u][v]&64?60:46);if(m[u
 ][                     v]&         16)   {c(   u,v                     );
  ;   return;;;}}}}Z(   int/**/a,   int   b){   }e(   int/**/y,int/**/  x){
int               i ;         for         (i=         a;i               <=a
+S;i++)d(y,x,i,b),d(y,x,i,b+L);for(i=b;i<=b+L;i++)d(y,x,a,i),d(y,x,a+   S,i
 );                     ;;;         ;;;         ;;;               ;;;   ;
  mvwaddch(w,x,y,64);   ;;;   ;;;   ;;;   prefresh(   w,b,a,0,0   ,L-   1,S-1
);}             main(         int               V ,   char              *C[
  ]   ){FILE*f=   fopen(V==1?"arachnid.c"/**/   :C[   1],"r");int/**/x,y,c,
v=0         ;;;      initscr              ();               Z(Z         (raw
 ()   ,Z(   curs_set(0),Z(1   ,noecho()))),keypad(    stdscr,TRUE));w   =newpad
  (   300,  300               ) ;   for         (x=   255   ; x   >=0   ;x--
  )   for   (y=   255   ;y>=0;y--   )m[   x][   y]=   0;x=y=0;refresh( );while
  (   (c=                           fgetc (f)   )+1)                    {if(
0||c==10||  x==   256){x=0;y++;if(y==256  )break;;}   else{m[x][y]=(c   ==
'~'   ?64   : c   ==32              ?0:         16)   ;;x               ++;
      }}for(x=0   ;x<   256;x++)m   [x][0]=16   ,m[   x][   255]=16;for(y=0
;y<         256   ; y         ++)   m[0         ][y   ] =               16,
m[255][y]   =16   ;a=b=c=0;   x=y   =1;   do{v++;mvwaddch   (w,   y,x   ,m[
x][         y]&               32?   m[x                     ][y   ] &   16?
 0|   acs_map[l[m[x][y]&15]]:46 :   32);c==0163&&!(m[x][y+1]&16)?y++:   0;c
 ==   119         &&!         (m[                                       x][
 y-   1]&   16)   ?y--:0;;c   ==97  &&!(m[x-1][y]&16)?x--:0;c==100&&!(m[x+1
 ][   y]&   16)         ? x   ++:0              ;if(                    c==
 3-   1+1   ){endwin(   );;   return(0)   ;}x   -a<5?a>S-   5?a-=S-5:(a=0):
0;x               -a>         S-5?a<255   -S*         2?a               +=S
-5:(a=256-S):0;   y-b<5?b>L-5?b-=L-5:(b   =0)   :0;   y-b>L-5?b<255-L   *2?
b+=                                       L-5   :(b                     =256
-L)   :0;e(x,y);if(m[x][y]&64)break;}while((c=getch())!=-1);endwin();cu(Q);
printf(Q,v);}


Rinia is a tool for embedding CRCs in text files. Rinia will insert a human-readable checksum string in the text itself! ^_^

             /*                                     ,*/
            #include                              
             #include/*                     _  ,o*/  
             #define  c(C)/*     -      . */return      ( C); /*    2004*/
              #include   /*.   Moekan           "'   `\b-'     */
                typedef/*  */char   p;p* u                     ,w       [9
                  ][128] ,*v;typedef  int _;_   R,i,N,I,A               ,m,o,e
             [9],  a[256],k    [9], n[               256];FILE*f       ;_ x   (_ K,_ r
        ,_ q){;   for(;                                         r<     q    ; K       =((
     0xffffff)   &(K>>8))^                                        n[255     &        ( K
   ^u[0        +                                     r  ++      ]     )]);c          (K
  )}        _ E                           (p*r,    p*q  ){     c(          f         =
          fopen                     (r  ,q))}_   B(_ q){c(    fseek        (f,      0
        ,q))}_ D(){c(  fclose(f ))}_  C(  p    *q){c(  0-    puts(q    )   )}_/*   /
      */main(_ t,p**z){if(t<4)c(   C(""    "\40 "
     /*b9213272*/""   ) )u=0;i=I=(E(z[1],"rb")) ?B(2)?0 :   (((o   =ftell
    (f))>=8)?(u     =(p*)malloc(o))?B(0)?0:!fread(u,o,1,f):0:0)?0:  D():0      ;if(
   !u)c(C("      bad\40input  "));if(E(z[2],"rb" )){for(N=-1;256> i;n[i++] =-1   )a[
   i]=0;       for(i=I=0;   i-1;i++)++a[R] ?(R==N)?( ++I>7)?(n[
  N]+1       )?0:(n [N   ]=i-7):0:   (N=R)    |(I=1):0;A =-1;N=o+1;for(i=33;i<127;i++
  )(        n[i   ]+  1&&N>a[i])?    N= a     [A=i]     :0;B(i=I=0);if(A+1)for(N=n[A];
 I<       8&&   (R  =fgetc(f ))>    -1&& i   N+7)?(R==A)?((*w[I
 ]             =u [i])?1:(*w[I]=   46))?(a             [I++]=i):0:0:0;D();}if(I<1)c(C(
              "  bad\40la" "yout  "))for(i            =0;256>(R=  i);n[i++]=R)for(A=8;
             A  >0;A --)   R  = ( (R&1)==0)          ?(unsigned int)R>>(01):((unsigned
            /*kero  Q'        ,KSS  */)R>>         1)^        0xedb88320;m=a[I-1];a[I
            ]=(m           R;R++)if(R-47&&R-92
           &&       R-(_)* w[i])*(                   v++)=    (p)R;*v=0;}for(sprintf
                  /*'_  G*/  (*w+1,              "%0"     "8x",x(R=time(i=0),m,o)^~
                0)   ;i<       8;++           i)u      [N+ i]=*(*w+i+1);for(*k=x(~
                  0,i=0     ,*a);i>-        1;      ){for (A=i;A-1?!w[i][++                 e[+ i]]:0;
             ) for( A=+i--;                 A

This is a configurable banner-like program : Convert a character glyph into a data file, or print a string using glyphs from a data file. Extra functionality: The program can also act as a Morse encoder, unarguably.

#include 
#include 
#include 
#include 
#define t(x) typedef x
#define G return
#define Y(x) x;x
#define e(s) exit(s);
#define b(x,o) x o x
#define Z while
#define y fclose
#define end static

t(signed)char U;t(struct) b(O,);

t(                                              U*)
H;                                              t(O
*)                                              *o;
struct O{ O* l, **h; void* L; } ; t(int)i; i P(U g) { G
isspace(g); } H D(H s){H p,r;if(!s)G 0;for(p=(H)s;*p &&
!P(*p); p++); if(r=malloc(p-s))for(p=r; *s&&! P(*s);p++
,s++)b(*,p=) s; G r;} void l(o p,O*x){*(o)x=* p; *p=x;}
#define m(x) do{ if(!(q = malloc(sizeof(O)))) e(1)q->l\
=0                                              ;q\
->                                              L=\
                  x ; } while (0)
              i(*R)(i) =putchar;i h(
           o f,H d,U c){O*q; f+=c;Z(d&&*d)
         { m(D(d)); l(f++, q); Z(*d && !P(*d
       )) d++; Z(*d && P(*d)) d++; } G b(,0);}
     void k() { static U b(c,;) ?R(c):(c='\n'); }
     i main (i Q,                   H *l){static o
   X;i t,j;                               switch (Q
 ){ case                                   1: { H
 *p, I                                           [] ={
"aH"                                             " "
"B"                                              "0"
" "                                              "B"
""                                              "B"
""                                              " "
"B"                                              ","
" "                                             ","
 " `"                                            "0 "
 "b0 "                                           "@, "
  "0 Hb,"                                  " B2 "
   "H0 b, B b"                            "H HB b`, "
     "H, @ 2 `, "                   "@2 H2 BH Bb"
      " b@","AH B0 BB B, , `0 b0 @, 0 Hb, B2 H0"
       " b, B bH HB b`, H, @ 2 `, @2 H2 BH Bb"
         " b@","0bHb, HbH `H2 @b, @H @0 B@ "
             "b@ bH0 bHB",".HHH","?`H0",
              ",b@b,"," +", 0}; p=I;

                  if (!(X=calloc(
              6<<6,sizeof(O*))))e(1)
           do{h(X,(*p)+1,**p);} Z(*(++p));
         D: if ((t = getchar()) >= 0) { k();
       goto u;}e(0)}case 2:{U *p,e[33]; b(i, )
     ,w;for(i=0;i<34;i++)i[e]=b(0,;w=);p=e; Z(1){
    t = (w == 200) ?                   10:getchar();
   switch(t) {                               case 0xa:
 case EOF:                                   if(w--
 ){R(1[l                                    ][0])
;for(i                                             =0,
p=e;i                                              <=w
;i+=                                              6){
R (                                              *p+
'+'                                              );*
p++                                              =0;
 ;}                                              R(
 0xa                                             );w
  =-1                                           ;}p=
    e-                                         1;case
      32:                                if (t<0) e(
       0)                                break; /*/*
         /*/                                default : *
           p
                  |=(001<<(w%6));
              }if((++w%6)==0)p++;}e(
           0)}case 3:{O*u,*q,*x;U s[0400];
         i i;FILE*F; j:j=1;if(!(X=calloc(6<<
       6,sizeof(O*)))) e(1) if(!(F=fopen(j[l],
     "r")))e(1)Z(fgets(s,j<<8,F))(*s)&&h(X,s+j,*s
    );j=b(i,=)&0xff;                   i:u=0;x=X[i];
   Z(x){q=Y(*(                               o)x)=Y(u)
 =Y(x)=q;}                                   i[X]=u
 ;i=(i-2                                    +9)%(
sizeof                                             (s))
;if(i                                              ^j)
goto                                              i;;
y(F)                                              ; }
case                                              4:{
end                                              i i
 ;if                                              (!
 X){                                             i=j
  =1;                                           goto
    j;}                                         if(i){O
      **x                                ,*m=*(x=X);
       do*                                x=1[x];Z(++
         xL;Z(*p>=n){i=(*p++)-n;for(c=0;c<6;c++,i=i
     >>1){ if(b(!, i                   &&)(*p >= n))
   break;R(32+                               (i&1)*3);
 }}R(10);a                                   =a->l;
 }if(Q<2                                    )goto
D;if(*                                             l[2
]){R(                                              10)
;main                                              (4,
l);                                              }}}
Z(Q                                              ++<
1){                                              X+=
 t;                                              if
 ((t                                             &7)
  >3)                                           goto
    i;                                         else {
      t--                                ;putchar(t)
       ;t                                =(t&7)?t:t-
         '*'                                ;}}exit(0);
           }


Je suis définitivement fan.



0 Commentaires

Une fenêtre flottante pour les commentaires

Au départ, c'est en feuilletant le blog bd de kek puis d'autres, j'ai trouvé intéressante l'idée d'ouvrir une nouvelle fenêtre pour afficher les commentaires d'un billet.

Je me suis bricolé le mien en utilisant plutôt un DIV flottant, un appel Ajax pour charger le texte, et un coup de script de drag & drop pour le confort. Je garde :)

Quand j'aurais un peu de temps, je posterais le code.

Testé avec Firefox, IE et Chrome.



9 Commentaires

Ext Desktop, un bureau pour les Google Apps ?

Avec les Googles Apps, l'utilisateur s'affranchit de plus en plus de son systême d'exploitation.

Voici une première expérience sur le sujet, avec l'intégration des Google Apps sur Ext Desktop, une extension du phénoménal Ext de Jack Slocum.

C'est avant tout un concept... Je peux avoir plusieurs documents ouverts, faire du copier-coller, bref gérer mon environnement documentaire un peu (pas beaucoup hein, mais un peu) comme sous windows avec Word. (Mais si, une barre des tâches, c'est un peu plus fonctionnel que des onglets. Vous allez me dire, autant développer un plugin Firefox pour afficher les onglets en tant que barre de tâche, et vous aurez raison)

Il faut avoir un compte Google activé sur les Google Apps, Calendar et Gmail. Sinon, se contenter du screenshot ;)

Voir la démo : Intégration de Google Apps avec Ext



3 Commentaires

Les alertes Google dans votre lecteur RSS

Si vous ne souhaitez plus recevoir les alertes Google dans votre boite mail débordée, il est désormais possible de les lire dans votre Google Reader.

Sur votre page de gestion des alertes, vous pouvez modifier le Mode d'envoi : sélectionnez Flux et les nouveautés du web comportant votre mot clé favori arrivent dans votre reader !

Extrééémement pratique.

merci
adi


1 Commentaires

Protéger son adresse email contre le spam

Il y a en permanence des spambots qui scrutent le contenu de nos pages web pour en relever les adresses mail. D'ailleurs, ce n'est pas bien dur à faire.

On le voit un peu partout, les webmasters emploient différentes astuces pour que la fameuse chaîne mailto:prenom.nom@gmail.fr n'apparaisse pas clairement dans le code source de la page.

Par exemple sur les Google Groups, l'adresse mail apparaît sous la forme preno...@gmail.fr : il faut cliquer dessus puis résoudre un captcha afin de la voir en entier.

Sachant que ces spambots se basent beaucoup sur la présence d'un caractère @ pour définir si une chaine est une adresse mail, on voit fleurir des adresses affichées en prenom DOT nom AT gmail DOT fr, ou encore plus parano, prenom DOT nom AT nospam gmail DOT fr, certains bots arrivant à détecter le premier cas.

Je vous propose la méthode suivante, que j'emploie depuis un moment et qui permet d'obtenir un vrai lien mailto:. Il s'agit d'employer Javascript pour réagir au clic sur le lien et définir l'adresse mailto que doit suivre le navigateur.

Il suffit de placer dans le HEAD de votre page web :

<script language="javascript">
 function mymailto(s1, s2) {
  window.location.href= 'mailto:' + s1 + '@' + s2;
 }
</script>

Ensuite, le lien mail, codé comme suit :

<a href="#" onclick="mymailto('bntcolin', 'gmail.com');" style="cursor:pointer;">Me contacter par mail</a>

Voici ce que cela donne :

Me contacter par mail

Enfin, l'évenement onclick peut être appliqué à d'autres balises, comme une image ou un div. Dans l'exemple ci-dessous, je combine un affichage de mon adresse mail par une image (avec une petite enveloppe pour troubler un éventuel OCR), avec un attribut ALT contenant mon adresse mail en toutes lettres (pour les navigateurs mobiles ou restreints), et la redirection du clic.

<div onclick="mymailto('bntcolin', 'gmail.com');" style="cursor:pointer;">
<a href="#"><img src="img/contact.gif" alt="bntcolin AT NOSPAM gmail DOT com" border="0" /></a>
</div>

Ce qui donne :

bntcolin AT NOSPAM gmail DOT com

Vous savez tout maintenant !

Excellent !
secuip
Génial!
quent1 - site


2 Commentaires

A propos de ce site

Ce site a été développé et designé à la main, avec des outils gratuits :

Merci à eux pour le service rendu :)

Ce site est hébergé chez OVH et pour l'instant, ça roule.



0 Commentaires
Powered by quedalle           Copier le contenu de ce blog sans le citer, c'est le Mal           re.bot           Citroulette