# articles

feed_id: https://tiger-222.fr/index.php?mode=links&id=20130701223459
title: Module python Multi-Screen Shot
uri: Module-python-Multi-Screen-Shot
url: https://tiger-222.fr/?d=2013/07/01/22/34/59-module-python-multi-screen-shot
content:
MSS pour <span style="font-style: italic;">Multi-Screen Shot</span>.<br/>
<br/>
Il s'agit d'un module python qui ne doit faire qu'une seule chose, et la faire bien&nbsp;: prendre des captures d'écran.<br/>
Hm... Il y a déjà la dose qui existe me direz-vous. Oui, Mais&nbsp;! Je ne souhaitais pas intégrer des monstres tels que <a href="http://wiki.python.org/moin/PyQt">Qt</a>, <a href="http://sourceforge.net/projects/pywin32/">win32</a> ou encore <a href="http://www.wxpython.org/">wx</a> ; et que ça soit <a href="http://www.pythonware.com/products/pil/">PIL</a> ou <a href="https://pypi.python.org/pypi/Pillow">Pillow</a>, aucun ne gère le multi-écran.<br/>
<br/>
Le module MSS a été pensé dans le but de combler ces vides&nbsp;:<br/>
<ul>
<li>gèrer le <span style="font-weight: bold;">multi-écran</span>,</li>
<li>tout en étant <span style="font-weight: bold;">multiplate-forme</span>,</li>
<li>et en utilisant seulement du <span style="font-weight: bold;">python pur</span>, aucun module externe</li>
</ul>
Pour plus d'informations sur le fonctionnement interne de MSS&nbsp;: <a href="http://tiger-222.fr/index.php?d=2013/08/07/18/39/49-gnulinux-python-pur-capture-decran">GNU/Linux</a> • <a href="http://tiger-222.fr/index.php?d=2013/08/25/19/00/12-mac-python-natif-capture-decran">Mac</a> • <a href="http://tiger-222.fr/index.php?d=2013/08/05/21/35/31-windows-python-pur-capture-decran">Windows</a><br/>
<br/>
<hr />
<h2 id="telecharger">Téléchargement</h2>
<br/>
Tous les fichiers nécessaires se trouvent sur la <a href="https://github.com/BoboTiG/python-mss">page du projet (GitHub)</a>.<br/>
Ou vous pouvez l'installer simplement en utilisant <a href="http://sametmax.com/votre-python-aime-les-pip/">pip</a>&nbsp;: <code class="language-shell">pip install mss</code>
<br/>
<br/>
<hr />
<h2 id="dep">Dépendances et pré-requis</h2>
<br/>
Python. Et c'est tout&nbsp;:)<br/>
MSS est écrit en Python pur,  utilisation intensive  de <span style="font-weight: bold;">ctypes.</span> ctypes a été officiellement intégré à Python depuis la version 2.5, pour les versions précédentes, il existe sous forme de module externe.<br/>
<br/>
<hr />
<h2 id="support">Support</h2>
<br/>
Voici le <a href="https://tiger-222.fr/tout/python-mss/support.html">tableau de compatibilité</a>, n'hésitez pas à ouvrir un <a href="https://github.com/BoboTiG/python-mss/issues">billet</a> pour me prévenir si vous avez pu tester MSS pour les configurations non testées.<br/>
<br/>
<hr />
<h2 id="usage">Utilisation</h2>
<br/>
Si vous souhaitez simplement tester le fonctionnement de MSS sur votre système, téléchargez le fichier <span style="font-weight: bold;">mss.py</span>, puis&nbsp;:<br/>
<pre><code class="language-bash">$ python mss.py</code></pre>
Le script prendra une capture par écran, suivi d'une capture globale.<br/>
<br/>
Si vous souhaitez intégrer MSS à un de vos projet, le module dispose des classes <code class="language-python">MSSLinux</code> et <code class="language-python">MSSWindows</code>, à appeler suivant votre système. Afin d'avoir plus de détails, il est possible de passer l'argument <code class="language-python">debug=True</code>. Utilisez-le si vous devez reporter un bogue.<br/>
Chacune de ces classes contient la méthode <code class="language-python">save(oneshot=False)</code>.<br/>
<pre><code class="language-python"># Vous pouvez déterminer automatiquement quelle classe utiliser&nbsp;:<br/>
from platform import system<br/>
from mss import *<br/>
<br/>
systems = {<br/>
	'Linux' &nbsp;: MSSLinux,<br/>
	'Windows': MSSWindows,<br/>
	'Darwin'&nbsp;: MSSMac<br/>
}<br/>
try:<br/>
	MSS = systems[system()]<br/>
except KeyError:<br/>
	err = 'System "{0}" not implemented.'.format(system())<br/>
	raise NotImplementedError(err)<br/>
<br/>
# Ou alors simplement importer la classe qu'il vous faut&nbsp;:<br/>
# from mss import MSSLinux as MSS<br/>
<br/>
try:<br/>
	mss = MSS()<br/>
<br/>
	# Une capture d'écran par moniteur<br/>
	for filename in mss.save():<br/>
		print('File "{0}" created.'.format(filename))<br/>
<br/>
	# Un seul fichier pour les capturer tous&nbsp;:)<br/>
	for filename in mss.save(oneshot=True):<br/>
		print('File "{0}" created.'.format(filename))<br/>
except Exception as ex:<br/>
	print(ex)<br/>
	raise<br/>
</code></pre>
<br/>
<hr />
<h2 id="bonus">Bonus</h2>
<br/>
Juste pour le fun, j'ai mis en place une <a href="https://tiger-222.fr/tout/python-mss/galerie/">galerie d'images</a> sans prétention afin d'exposer les captures d'écran <span style="font-style: italic;">oneshot</span> que vous me ferez parvenir ☺


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130624155707
title: Vie privée : les fuites
uri: Vie-privée-les-fuites
url: https://tiger-222.fr/?d=2013/06/24/15/57/07-vie-privee-les-fuites
content:
<h2>Pourquoi cet article ?</h2>
<br/>
Pour avoir un recueil de documents qui serviront à prouver que la vie privée sur le web, et bien... Ce n'est pas vraiment ça&nbsp;!<br/>
À force de rechercher des preuves pour mes interlocuteurs/interlocutrices lorsque je parle des grandes firmes comme Apple, Google ou Facebook, je me suis dit qu'un article à jour serait intéressant.<br/>
Le voici donc&nbsp;! Couplé aux autres informations portant sur la <a href="https://tiger-222.fr/index.php?d=2013/04/05/16/16/53-telecommunications-et-securite">sécurité des télécommunications</a>, il y a de quoi faire réagir.<br/>
<br/>
Pour ceux et celles qui pensent qu'ils/elles n'ont rien à cacher, visionnez les quelques <a href="https://tiger-222.fr/#videos">vidéos en bas de page</a>.<br/>
Pour agir => <a href="http://www.controle-tes-donnees.net/">Reprenez le contrôle de vos données&nbsp;!</a>, <a href="http://prism-break.org/">PRISM Break</a>.<br/>
<br/>
<hr/>
<h3 id="etat-francais">État français</h3>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[8] [9] [10]</span></li>
<li>2013-05-07&nbsp;: <a href="http://lexpansion.lexpress.fr/high-tech/internet-sms-comment-thales-va-mettre-les-reseaux-francais-sur-ecoute_383757.html">Internet, SMS&nbsp;: comment Thales va mettre les réseaux français sur écoute</a></li>
<li>2013-07-04&nbsp;: <a href="http://korben.info/infrastructure-de-mutualisation.html">Infrastructure de mutualisation</a></li></ul>
<br/>
<h3 id="apple">Apple</h3>
<span style="font-style: italic;">Liste des services, logiciels et matériels faussement transparents&nbsp;:</span> iMessage, iPad, iPhone, iPod, iTunes, SIRI<br/>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[1]</span></li>
<li>2011-04-20&nbsp;: <a href="http://reflets.info/avec-apple-nous-sommes-bien-pris-en-mains-trop/">Avec Apple, nous sommes bien pris en mains… Trop ?</a></li>
<li>2011-10-20&nbsp;: <a href="http://reflets.info/siri-apple-se-lance-t-il-dans-le-fichage-biometrique-de-masse/">SIRI&nbsp;: Apple se lance t-il dans le fichage biométrique de masse ?</a></li>
<li>2012-09-05&nbsp;: <a href="http://rt.com/news/apple-patent-transmission-block-408/">No shooting at protest? Police may block mobile devices via Apple</a></li>
<li>2013-10-19&nbsp;: <a href="http://www.developpez.com/actu/62821/iMessage-Apple-pourrait-lire-vos-messages-le-chiffrement-de-son-application-mis-en-cause-par-deux-chercheurs/">iMessage&nbsp;: Apple pourrait lire vos messages</a></li>
<li>2013-10-21&nbsp;: <a href="http://korben.info/imessages-hack-video.html">Démo vidéo d’une interception sur iMessages</a></li></ul>
<br/>
<h3 id="facebook">Facebook</h3>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[2] [4] [5] [8] [9]</span></li>
<li>2013-06-13&nbsp;: <a href="http://www.nikopik.com/2013/06/facebook-communique-tous-vos-messages-censes-etre-prives.html">Facebook communique tous vos messages censés être privés</a></li>
<li>2013-06-13&nbsp;: <a href="http://www.nikopik.com/2013/03/facebook-laisse-vos-photos-accessibles-a-tous-depuis-des-annees-et-ca-ne-risque-pas-de-changer.html">Facebook laisse vos photos accessibles à tous depuis des années... et ça ne risque pas de changer</a></li>
<li>2013-06-20&nbsp;: <a href="http://www.theatlanticwire.com/technology/2013/06/facebooks-former-security-chief-now-works-nsa/66432/">Facebook's Former Security Chief Now Works for the NSA </a></li>
<li>2013-09-30&nbsp;: <a href="http://pro.clubic.com/blog-forum-reseaux-sociaux/facebook/actualite-588844-twitter-facebook-partage-donnees-chaines-television.html">Facebook partage ses données avec les chaînes de télévision</a></li></ul>
<br/>
<h3 id="fbi">FBI</h3>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[2] [3] [7]</span></li>
<li>2013-06-05&nbsp;: <a href="http://www.nikopik.com/2013/06/le-fbi-exige-que-tous-les-gadgets-et-logiciels-possedent-un-niveau-de-securite-faible-pour-faire-des-ecoutes.html">Le FBI exige que tous les gadgets et logiciels possèdent un niveau de sécurité faible pour faire des écoutes</a></li></ul>
<br/>
<h3 id="google">Google</h3>
<span style="font-style: italic;">Liste des services et logiciels faussement transparents&nbsp;:</span> Android, Google AdSense, Google AdWords, Google Agenda, Google Analytics, Google Code, Google Docs, Google Drive, Google Fonts, Google Glass, Google Music, Google+, GMail, Google Group, Google Street View, Picasa, Youtube<br/>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[1] [2] [3] [4] [7] [8] [11]</span></li>
<li>2013-03-12&nbsp;: <a href="http://reflets.info/google-la-mise-en-place-de-laspirateur-a-donnees-personnelles/">Google&nbsp;: la mise en place de l’aspirateur à données personnelles</a></li>
<li>2013-06-04&nbsp;: <a href="http://sametmax.com/non-aux-google-glasses/">Non aux Google Glasses</a></li>
<li>2013-08-13&nbsp;: <a href="http://www.sfgate.com/technology/businessinsider/article/GOOGLE-If-You-Use-Gmail-You-Have-No-Legitimate-4730587.php">GOOGLE: If You Use Gmail, You Have 'No Legitimate Expectation Of Privacy'</a></li></ul>
<br/>
<h3 id="hp">HP</h3>
<span style="font-style: italic;">Liste des services et produits impactés&nbsp;:</span> Portables, StoreVirtual (et du coup, très certainement d'autres produits)<br/>
<ul>
<li>2010-12-14&nbsp;:<a href="https://www.securityweek.com/backdoor-vulnerability-discovered-hp-msa2000-storage-systems">Backdoor Vulnerability Discovered on HP MSA2000 Storage Systems</a></li>
<li>2013-07-11&nbsp;: <a href="http://www.theregister.co.uk/2013/07/11/hp_prepping_fix_for_latest_storage_vuln/">HP admits to backdoors in storage products</a></li>
<li>2013-08-30&nbsp;: <a href="http://www.reddit.com/r/RTLSDR/comments/1le3if/so_i_discovered_that_my_hp_laptop_leakstransmits/">So I discovered that my HP laptop leaks/transmits its built-in mic audio somewhere around 24Mhz</a></li></ul>
<br/>
<h3 id="microsoft">Microsoft</h3>
<span style="font-style: italic;">Liste des services, logiciels et consoles faussement transparents&nbsp;:</span> Microsoft Outlook, Microsoft Live, SkyDrive, Skype, XBox One<br/>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[2] [4] [6] [8]</span></li>
<li>2012-06-23&nbsp;: <a href="http://sebsauvage.net/rhaa/index.php?2012/08/23/14/46/48-microsoft-live-n-est-pas-fait-pour-les-etres-humains">Microsoft Live n'est pas fait pour les êtres humains</a></li>
<li>2012-11-06&nbsp;: <a href="http://www.numerama.com/magazine/24199-drm-espion-microsoft-veut-compter-les-spectateurs-chez-vous.html">DRM espion&nbsp;: Microsoft veut compter les spectateurs chez vous&nbsp;!</a></li>
<li>2013-03-09&nbsp;: <a href="http://sebsauvage.net/links/?dhCUyw">Skype pris en flagrant délit d'espionnage des conversations en Chine</a></li>
<li>2013-03-15&nbsp;: <a href="http://tech.slashdot.org/story/13/03/15/1241229/russian-fsb-can-reportedly-tap-skype-calls">Russian FSB Can Reportedly Tap Skype Calls</a></li>
<li>2013-05-14&nbsp;: <a href="http://www.h-online.com/security/news/item/Skype-with-care-Microsoft-is-reading-everything-you-write-1862870.html">Skype with care – Microsoft is reading everything you write</a></li>
<li>2013-05-22&nbsp;: <a href="http://www.presse-citron.net/la-xbox-one-ecoutera-continuellement-vos-conversations">La Xbox One écoutera continuellement vos conversations</a></li>
<li>2013-06-03&nbsp;: <a href="http://www.neowin.net/news/man-arrested-for-child-erotica-stored-on-his-skydrive">Man arrested for child erotica stored on his SkyDrive</a></li>
<li>2013-06-20&nbsp;: <a href="https://www.schneier.com/blog/archives/2013/06/new_details_on.html">New Details on Skype Eavesdropping</a></li>
<li>2013-06-23&nbsp;: <a href="http://www.zdnet.fr/actualites/le-porno-interdit-sur-skydrive-temoignage-d-un-utilisateur-francais-39775346.htm">Le porno interdit sur SkyDrive, témoignage d'un utilisateur français</a></li>
<li>2013-08-24&nbsp;: <a href="http://www.megaleecher.net/Windows_8_Spying_For_NSA">German Security Officers Warns Govt.&nbsp;: Microsoft Windows 8 too ‘dangerous’ to use</a></li></ul>
<br/>
<h3 id="nintendo">Nintendo</h3>
<span style="font-style: italic;">Liste des services, logiciels et consoles faussement transparents&nbsp;:</span> Nintendo 3DS<br/>
<ul>
<li>2012-11-01&nbsp;: <a href="http://www.numerama.com/magazine/27387-nintendo-suspend-sa-messagerie-sur-3ds-les-enfants-se-montraient-leurs-zizis.html">Nintendo suspend sa messagerie sur 3DS. Les enfants se montraient leurs zizis.</a> (on retient surtout que Nintendo a accès à tous vos messages...)</li></ul>
<br/>
<h3 id="nsa">NSA</h3>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[2] [5] [6] [7] [8] [10] [11]</span></li>
<li>2013-06-07&nbsp;: <a href="http://www.numerama.com/magazine/26172-prism-les-francais-concernes-par-l-espionnage-des-geants-du-web.html">PRISM&nbsp;: les Français concernés par l'espionnage des géants du web</a></li>
<li>2013-06-10&nbsp;: <a href="http://www.businessspectator.com.au/news/2013/6/10/technology/obama-identifies-surveillance-effort-trade-security">Obama identifies surveillance effort as a 'trade off' for security</a></li>
<li>2013-08-25&nbsp;: <a href="http://www.framablog.org/index.php/post/2013/08/25/nsa-mathematiques">Lettre ouverte à mes anciens collègues mathématiciens de la NSA</a></li>
<li>2013-09-16&nbsp;: <a href="http://www.tomsguide.fr/actualite/nsa-transactions-bancaires,22556.html">La NSA surveille aussi les cartes bancaires</a></li></ul>
<br/>
<h3 id="twitter">Twitter</h3>
<ul>
<li>2013-07-03&nbsp;: <a href="http://boingboing.net/2013/07/03/twitter-will-allow-advertisers.html">Twitter to allow advertisers to target your browsing history & email addresses</a></li></ul>
<h3 id="yahoo">Yahoo</h3>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[11]</span></li>
<li>2013-06-03&nbsp;: <a href="http://www.zdnet.fr/actualites/yahoo-laissez-nous-lire-vos-emails-ou-switchez-39790961.htm">Yahoo&nbsp;: laissez-nous lire vos emails ou switchez</a></li></ul>
<br/>
<h3 id="autres">Autres services, logiciels</h3>
<span style="font-style: italic;">Liste des services et logiciels faussement transparents, traitres&nbsp;:</span> LinkedIn, Snapchat<br/>
<ul>
<li>2013-10-16&nbsp;: <a href="http://nakedsecurity.sophos.com/2013/10/16/snapchat-admits-sharing-images-with-us-law-enforcement/">Snapchat admits sharing images with US law enforcement</a></li></ul>
<hr />
Dans un registre un peu plus <span style="font-style: italic;">physique</span>, la poste américaine garde des traces de <span style="font-weight: bold;">tous</span> les envois hors du territoire (nom, adresse, et toutes les informations possibles de rappatrier). Vous avez très certainement déjà acheté sur Amazon ou eBay (en autres), non ?<br/>
<ul>
<li>2013-07-03&nbsp;: <a href="http://www.nytimes.com/2013/07/04/us/monitoring-of-snail-mail.html">U.S. Postal Service Logging All Mail for Law Enforcement</a></li></ul>
<hr />
<h3 id="videos">Conférences, vidéos</h3>
<ul>
<li>2013-06-21&nbsp;: <a href="http://www.youtube.com/watch?v=BbkbdYoffX4">Si, vous avez quelque chose à cacher</a>, de <a href="http://pixellibre.net/">Numendil</a></li>
<li>2013-08-13&nbsp;: <a href="https://www.youtube.com/watch?v=E1htQOYEaDU">Comme votre vie peut devenir flippante... en très peu de temps</a></li>
<li>2013-09-25&nbsp;: <a href="https://www.youtube.com/watch?v=ugGqI24J23s">Le hacker Jacob Appelbaum explique le système de surveillance au Parlement européen </a></li></ul>
<hr />
<h3 id="refs">Références multiples</h3>
<ul>
<li><span style="font-weight: bold;">[1]</span> 2013-05-12&nbsp;: <a href="http://boingboing.net/2013/05/12/apple-can-decrypt-iphones-for.html">Apple can decrypt iPhones for cops; Google can remotely "reset password" for Android devices</a></li>
<li><span style="font-weight: bold;">[2]</span> 2013-06-07&nbsp;: <a href="http://www.wikistrike.com/article-le-fbi-a-acces-aux-serveurs-de-google-skype-et-facebook-118329177.html">Le FBI a accès aux serveurs de Google, Skype et Facebook</a></li>
<li><span style="font-weight: bold;">[3]</span> 2013-03-27&nbsp;: <a href="http://yro.slashdot.org/story/13/03/26/2328250/real-time-gmail-spying-a-top-priority-for-fbi-this-year">Real-Time Gmail Spying a 'Top Priority' For FBI This Year</a></li>
<li><span style="font-weight: bold;">[4]</span> 2012-10-13&nbsp;: <a href="http://sebsauvage.net/links/?HFeVuQ">German police monitors Skype, GoogleMail and Facebook chat</a></li>
<li><span style="font-weight: bold;">[5]</span> 2013-06-22&nbsp;: <a href="http://www.wikistrike.com/article-snowden-juge-l-agence-britannique-pire-que-la-nsa-118656221.html">Snowden juge l'agence britannique "pire" que la NSA</a></li>
<li><span style="font-weight: bold;">[6]</span> 2013-07-11&nbsp;: <a href="http://www.guardian.co.uk/world/2013/jul/11/microsoft-nsa-collaboration-user-data">Revealed: how Microsoft handed the NSA access to encrypted messages</a></li>
<li><span style="font-weight: bold;">[7]</span> 2013-08-27&nbsp;: <a href="http://www.framablog.org/index.php/post/2013/08/27/assange-google-nsa">Google et le gouvernement des États-Unis main dans la main selon Julian Assange</a></li>
<li><span style="font-weight: bold;">[8]</span> 2013-09-01&nbsp;: <a href="http://www.bortzmeyer.org/crypto-protection.html">La cryptographie nous protège t-elle vraiment de l'espionnage par la NSA ou la DGSE ?</a></li>
<li><span style="font-weight: bold;">[9]</span> 2013-09-13&nbsp;: <a href="http://www.zdnet.fr/actualites/paypal-va-partager-avec-facebook-criteo-mediaplex-les-donnees-de-ses-utilisateurs-en-opt-out-39793971.htm">PayPal va partager avec Facebook, Criteo, Mediaplex... les données de ses utilisateurs. En opt-out</a></li>
<li><span style="font-weight: bold;">[10]</span> 2013-10-21&nbsp;: <a href="http://www.lemonde.fr/technologies/article/2013/10/21/comment-la-nsa-espionne-la-france_3499758_651865.html">Comment la NSA espionne la France</a></li>
<li><span style="font-weight: bold;">[11]</span> 2013-10-21&nbsp;: <a href="http://www.techdirt.com/articles/20131030/09554125066/nsa-breaks-into-yahoo-googles-data-centers-without-their-knowledge.shtml">NSA Breaks Into Yahoo And Google's Data Centers Without Their Knowledge</a></li></ul>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130617152405
title: Inno Setup : page personnalisée
uri: Inno-Setup-page-personnalisée
url: https://tiger-222.fr/?d=2013/06/17/15/24/05-inno-setup-page-personnalisee
content:
<div style="text-align:center;"><img src="media/f50f9162.inno-setup-custom-listbox.png" data-original-source="http://tiger-222.fr/img/inno-setup-custom-listbox.png" alt="" /></div><br/>
<a href="http://www.jrsoftware.org/isinfo.php">Inno Setup</a> c'est bien, mais la documentation est un peu brouillon et trouver des informations précises n'est pas chose facile.<br/>
Pour la prochaine version de Pombo, j'avais besoin d'avoir une liste contenant plusieurs choix sur une seule page, et surtout pouvoir utiliser l'élément sélectionné par la suite.<br/>
<br/>
Voici le code source de <a href="http://tiger-222.fr/files/getmark.iss">getmark.iss</a>, pour l'utiliser, il suffit d'ajouter cette instruction dans la section <span style="font-style: italic;">[Code]</span>&nbsp;:<br/>
<pre><code class="language-clike">#include "getmark.iss"</code></pre>
<br/>
Avant d'entrer plus dans les détails, pour récupérer l'élément sélectionné (pour les section <span style="font-style: italic;">[Files]</span> ou <span style="font-style: italic;">[Registry]</span> par exemple)&nbsp;:<br/>
<pre><code class="language-clike">{code:GetTheMark} renverra "Acer"</code></pre>
<br/>
<hr />
<h2>Dans les entrailles du <span style="text-decoration: line-through;">monstre</span> script</h2>
<br/>
Voici les différents <span style="font-style: italic;">composants</span>&nbsp;:<br/>
<ul>
<li>une procédure standard <a href="http://www.jrsoftware.org/ishelp/index.php?topic=scriptevents&anchor=InitializeWizard">InitializeWizard</a>&nbsp;: ajout de la page personnalisée dans l'installeur global</li>
<li>une procédure standard <a href="http://www.jrsoftware.org/ishelp/index.php?topic=scriptevents&anchor=CurPageChanged">CurPageChanged</a>&nbsp;: pour déterminer quand il y a un changement de page (boutons <span style="font-style: italic;">Précédent</span> et <span style="font-style: italic;">Suivant</span>)</li>
<li>une procédure <span style="font-style: italic;">CreatePageStealthMode</span>&nbsp;: création de la page personnalisée</li>
<li>une procédure <span style="font-style: italic;">OnPageStealthModeClicked</span>&nbsp;: action(s) à effectuée(s) lorsqu'un choix est fait dans la liste</li>
<li>une fonction <span style="font-style: italic;">GetTheMark()</span>&nbsp;: permet de récupérer le choix de la liste pour les autres étapes/sections</li>
</ul>
Les procédures suivantes s'occupent de l'intégration de la page personnalisée.<br/>
<br/>
C'est simple, ici on vient ajouter la page personnalisée à l'installeur&nbsp;:<br/>
<pre><code class="language-clike">procedure InitializeWizard;<br/>
begin<br/>
	CreatePageStealthMode;<br/>
end;</code></pre>
<br/>
La portion de code suivante sert uniquement à désactiver le bouton <code class="language-markup">Suivant</code> lorsque l'on est sur la page personnalisée afin d'obligé l'utilisateur à faire un choix&nbsp;:<br/>
<pre><code class="language-clike">procedure CurPageChanged(CurPageID: Integer);<br/>
begin<br/>
	if CurPageID = PageStealthMode.ID then<br/>
		if ChosenMark.ItemIndex = -1 then<br/>
			WizardForm.NextButton.Enabled&nbsp;:= False;<br/>
end;</code></pre>
<br/>
<hr />
Les procédures suivante s'occupent de la création et de la gestion de la page personnalisée.<br/>
<br/>
La fonction <a href="http://thierryaim.developpez.com/tutoriel/innosetup/iscode/#LV-1-1">CreateCustomPage()</a> permet de spécifier après quelle page standard il faut insérer la nôtre, un titre et un texte explicatif. Ici, je choisis d'afficher la page personnalisée juste après la page qui affiche la licence (<code class="language-markup">wpLicense</code>). La liste de choix est une simple <a href="http://www.jrsoftware.org/ishelp/index.php?topic=scriptclasses&anchor=TListBox">TListBox</a> ajoutée en pleine page&nbsp;:<br/>
<pre><code class="language-clike">procedure CreatePageStealthMode;<br/>
var<br/>
	j&nbsp;: Integer;<br/>
begin<br/>
	PageStealthMode&nbsp;:= CreateCustomPage(wpLicense, ExpandConstant('{cm:marque_title}'), ExpandConstant('{cm:marque_texte}'));<br/>
	ChosenMark&nbsp;:= TListBox.Create(PageStealthMode);<br/>
	ChosenMark.Width&nbsp;:= PageStealthMode.SurfaceWidth;<br/>
	ChosenMark.Height&nbsp;:= PageStealthMode.SurfaceHeight - 10;<br/>
	ChosenMark.Parent&nbsp;:= PageStealthMode.Surface;<br/>
	{ Assignement de la procédure lorsqu'un élément est choisi. }<br/>
	ChosenMark.OnClick&nbsp;:= @OnPageStealthModeClicked;<br/>
	for j&nbsp;:= 0 to High(Marks) do begin<br/>
		ChosenMark.Items.Add(Marks[j]);<br/>
	end;<br/>
end;</code></pre>
<br/>
On stocke l'élément sélectionné dans la variable <code class="language-markup">TheMark</code> puis on réactive le bouton <code class="language-markup">Suivant</code>, ça peut toujours être pratique&nbsp;:<br/>
<pre><code class="language-clike">procedure OnPageStealthModeClicked(Sender: TObject);<br/>
var<br/>
	list&nbsp;: TListBox;<br/>
begin<br/>
	list&nbsp;:= TListBox(Sender);<br/>
	TheMark&nbsp;:= list.Items[list.ItemIndex];<br/>
	WizardForm.NextButton.Enabled&nbsp;:= True;<br/>
end;</code></pre>
<br/>
Il nous reste la fonction <code class="language-markup">GetTheMark()</code>, qui est on ne peut plus simple&nbsp;:<br/>
<pre><code class="language-clike">function GetTheMark(Param: String): String;<br/>
begin<br/>
	Result&nbsp;:= TheMark;<br/>
end;</code></pre>
Elle sert uniquement à avoir accès à l'élément sélectionné en dehors du code, pour les autres pages/étapes de l'installeur.


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130531190156
title: Pombo 0.0.10 & Pombo GUI
uri: Pombo-0-0-10-Pombo-GUI
url: https://tiger-222.fr/?d=2013/05/31/19/01/56-pombo-0010-pombo-gui
content:
<div style="text-align:center;"><q><span style="font-weight: bold;"><span style="font-size:12pt;">TL;DR</span></span><br/>
<span style="font-weight: bold;">Liens</span>&nbsp;: <a href="https://github.com/BoboTiG/pombo/blob/master/packages/pombo-0.0.10.tar.gz?raw=true">GNU/Linux</a> • <a href="https://github.com/BoboTiG/pombo/blob/master/packages/pombo-0.0.10_setup.exe?raw=true">Windows</a> • <a href="https://github.com/BoboTiG/pombo">GitHub</a> • <a href="http://bobotig.fr/index.php?c=projets/pombo/">Projet</a> • <a href="https://github.com/BoboTiG/pombo-config">Pombo GUI</a><br/>
Beaucoup de modifications ont été apportées, pensez à faire une copie du fichier de configuration et à désinstaller l'ancienne version de Pombo avant d'installer la nouvelle.<br/>
</q><br/>
<img src="media/5ec2b24f.pombo.png" data-original-source="http://tiger-222.fr/img/pombo.png" /><br/>
<span style="color:gray;">Il est pas beau mon logo ?</span></div><br/>
<hr/>
Plus d'un an après la version 0.0.9, qui date du 20 janvier 2012, voici que je vous propose la version 0.0.10&nbsp;!<br/>
Beaucoup de modifications apportées, avec des corrections, des remaniements de code (mais pas trop) et de belles suprises&nbsp;:)<br/>
<br/>
<hr />
<h2>Késako ?</h2>
<br/>
Qu'est-ce que <span style="font-style: italic;">Pongo</span> ? Euh non, Pombo ?!<br/>
Il s'agit d'un logiciel dans la même lignée que <a href="http://preyproject.com">Prey</a>, il permet, en cas de vol ou de perte de l'ordinateur, de récupérer des informations qui peuvent être utiles pour le retrouver. Le système est simplissime, Pombo enverra à intervalles réguliers des rapports contenant&nbsp;:<br/>
<br/>
<ul>
<li>le nom du système</li>
<li>l'adresse IP publique</li>
<li>la date et l'heure</li>
<li>les informations sur toutes les interfaces réseau (filaires et wifi), y compris l'adresse matérielle (MAC) du point d'accès WiFi auquel l'ordinateur est connecté</li>
<li>les connexions réseau en cours</li>
<li>les informations sur les routeurs proches</li>
<li>la liste de tous les points d'accès WiFi proches, avec leur adresse matérielle (MAC), leur SSID et leur puissance</li>
<li>une capture d'écran</li>
<li>une photo par la webcam (si vous en avez une)</li>
</ul>
Le tout chiffré à l'aide de <a href="http://gnupg.org/">GnuPG</a>, fonctionnel sous GNU/Linux et Microsoft Windows (Mac peut-être ?) et en libre service s'il vous plaît (licence <a href="http://opensource.org/licenses/Zlib">Zlib</a>).<br/>
Le point fort de Pombo se situe au niveau de l'hébergement, vous pouvez envoyer les rapports où bon vous semble et le nombre de serveurs est illimité.<br/>
<br/>
<hr />
<h2>Attaquons</h2>
<br/>
Le vif du sujet, avec la liste des changement qu'apporte cette nouvelle version&nbsp;:<br/>
<br/>
<ul>
<li>possibilité d'envoyer les rapports sur un serveur protégé par une authorisation basique (style htaccess)</li>
<li>prise en charge d'un proxy, utile si vous être bloqués derrière celui d'une entreprise [merci à Jérôme Deheyn] <span style="color:red;">***</span></li>
<li>prise en compte des adresses IPv6 (module python <a href="https://pypi.python.org/pypi/IPy/">IPy</a> pour la validation des adresses)</li>
<li>prise en compte de la modification du fichier de configuration sans redémarrer Pombo</li>
<li>prise en compte des serveurs HTTPS, urllib* chiaient dans la colle (module python <a href="http://fr.python-requests.org/en/latest/">requests</a>, un bijou celui-là)</li>
<li>ajout d'un système de journalisation des informations (module logging)</li>
<li>ajout de l'argument <span style="font-style: italic;">update</span> pour vérifier la présence de MàJ</li>
<li>GNU/Linux&nbsp;: compatibilité avec python 3 (pour Windows, il y a trop de soucis avec <a href="http://www.pythonware.com/products/pil/">PIL</a>)</li>
<li>GNU/Linux&nbsp;: amélioration de la routine qui détermine l'utilisateur courant</li>
<li>GNU/Linux&nbsp;: amélioration du script install.sh pour prendre en compte les modules python</li>
<li>GNU/Linux&nbsp;: ajout du script uninstall.sh</li>
<li>GNU/Linux&nbsp;: révision du script cron, dorénavant un fichier sera créé dans /etc/cron.d/</li>
<li>Windows&nbsp;: étoffement de l'installeur (python, GnuPG et WLAN Dump en options)</li>
<li>Windows&nbsp;: dorénavant le dossier pombo et le fichier pombo.conf seront des fichiers système cachés </li>
<li>Windows&nbsp;: ajout des versions de VideoCapture et PIL pour l'argument <span style="font-style: italic;">version</span></li>
<li>Windows&nbsp;: mise à jour de python (2.7.3 => 2.7.5)</li>
<li>Windows&nbsp;: mise à jour de la bibliothèque VideoCapture</li>
</ul>
<span style="color:red;">***</span> J'aurai besoin de plus de testeurs, si vous vous en sentez l'âme&nbsp;:)<br/>
<br/>
Sous Windows, l'installeur pèse 6 146 421 octets car j'intègre WLAN Dump et GnuPG (seulement le binaire ainsi que la DLL associée [iconv.dll]). Bien entendu, hormis Pombo, rien n'est obligatoire à l'installation. Cependant, si vous n'installez pas python, n'oubliez pas d'installer les modules nécessaires.<br/>
<br/>
Vous aurez remarqué deux inconnus dans ce lot&nbsp;: Pombo GUI et WLAN Dump.<br/>
<span style="text-decoration: underline;">Pombo GUI</span> est une interface graphique pour le fichier de configuration. Elle est développée en C++/Qt (donc multiplateforme) disponible en anglais et en français. L'utilisation de Qt Linguist rend le système de traduction plus que facile, donc si vous ne trouvez pas votre bonheur, n'hésitez pas à m'envoyer de nouvelles. Voici une capture d'écran&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/dbf01710.Windows-7.png" data-original-source="http://tiger-222.fr/img/Windows-7.png" /><br/>
<span style="color:gray;">Ça en jette, non ?</span></div><br/>
<span style="text-decoration: underline;">WLAN Dump</span> est un fichier batch qui utilise <a href="http://www.symantec.com/connect/sites/default/files/WLAN.zip">wlan.exe</a> et qui permet d'avoir un semblant de résultat correct pour le listage des réseaux WiFi sous Windows XP. En effet, la commande <span style="font-style: italic;">netsh wlan show all</span> n'existe pas sur ce système... Pour plus d'informations sur ce wlan.exe, <a href="http://www.symantec.com/connect/articles/how-capture-and-deploy-wlan-profiles">cet article</a> devrait vous combler.<br/>
<br/>
<hr />
<h3>Du côté des paramètres</h3>
<br/>
Voici les petits nouveaux&nbsp;:<br/>
<br/>
<ul>
<li><span style="font-style: italic;">time_limit</span> (chiffre)&nbsp;: c'est le temps d'attente entre chaque rapport. Lors d'un vol, ce temps est divisé par 3. Ça permet un plus grand contrôle sur le temps (j'aime cette phrase&nbsp;!)</li>
<li><span style="font-style: italic;">enable_log</span> (booléen)&nbsp;: pour ceux et celles qui ont des soucis, activez-le afin d'avoir un maximum de détails</li>
<li><span style="font-style: italic;">use_proxy</span> (booléen)&nbsp;: permet de spécifier si oui ou non on est derrière un proxy</li>
<li><span style="font-style: italic;">use_env</span> (booléen)&nbsp;: si on est derrière un proxy, on peut décider d'utiliser les variables d'environnement HTTP_PROXY et HTTPS_PROXY</li>
<li><span style="font-style: italic;">http_proxy</span> et <span style="font-style: italic;">https_proxy</span>&nbsp;: dans le cas contraire, on utilise ces paramètres</li>
<li><span style="font-style: italic;">auth_server</span>&nbsp;: nom de domaine du serveur sur lequel il y a l'authentification basique</li>
<li><span style="font-style: italic;">auth_user</span>&nbsp;: le nom d'utilisateur pour l'authentification basique</li>
<li><span style="font-style: italic;">auth_pswd</span>&nbsp;: le mot de passe pour l'authentification basique</li>
</ul>
Le paramètre <span style="font-style: italic;">serverurl</span> a changé, s'il y a plusieurs serveurs, alors séparez-les par "|" et non plus par une virgule. Ce choix est du au fait que j'utilise QSettings pour Pombo GUI (ça permet de lire/écrire un fichier de configuration tel que celui de Pombo) et qu'il ne comprend pas la virgule. Tout simplement.<br/>
<br/>
Donc pensez à faire une copie du fichier de configuration avant de faire la mise à jour.<br/>
<br/>
<hr/>
<h3>Du côté des bugs</h3>
<br/>
Il y en avait un méchant qui faisait que les rapports ne changeaient pas de nom, du coup il n'y en avait qu'un seul. Pas terrible&nbsp;:s<br/>
Mais aussi&nbsp;:<br/>
<ul>
<li>correction du disfonctionnement lors d'un vol (avec l'option <span style="font-style: italic;">onlyipchange</span> il y avait une erreur de conception)</li>
<li>correction des délais entre chaque rapport (prise en compte du temps écoulé pour un rapport)</li>
<li>Windows&nbsp;: lorsque l'installeur créait la clef de registre, toutes les sous-clefs sont supprimées</li>
</ul>
Enfin, la suppression de l'option <span style="font-style: italic;">recompression</span> que j'ai jugé (à tort peut-être) inutile&nbsp;: les fichiers sont suffisamment petits et l'utilisation du JPG (95% d'entre vous) fait que le gain de poids est plus que dérisoire.<br/>
<br/>
<hr />
<h2>Note de fin</h2>
Cette version a pu être testée avec succès sur les systèmes suivant&nbsp;:<br/>
<br/>
<ul>
<li>Microsoft Windows XP</li>
<li>Microsoft Windows 7 32/64 bits</li>
<li>Microsoft Windows 8 64 bits</li>
<li>Debian GNU/Linux 64 bits</li>
<li>Lubuntu 13.04 32 bits, le compte Invité fonctionne aussi</li>
<li>Linux Mint 14</li>
</ul>
Si vous pouvez faire d'autres tests, notamment sur Mac, je suis preneur&nbsp;:)


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130521151524
title: C++/Qt : compilation statique sous Windows
uri: C-Qt-compilation-statique-sous-Windows
url: https://tiger-222.fr/?d=2013/05/21/15/15/24-cqt-compilation-statique-sous-windows
content:
Il y a plusieurs avantages à la compilation statique&nbsp;: léger gain en rapidité et une facilité de déploiement déconcertante (un seul exécutable qui comprend l'application ainsi que les bibliothèques de Qt et MinGW).<br/>
Par contre le poids du binaire généré sera bien plus lourd, vous pourrez toujours le réduire à l'aide d'<a href="http://upx.sourceforge.net/">UPX</a>.<br/>
<hr />
<h2>Du côté de Qt</h2>
<br/>
Avant toute chose, mettez un pack de bières au frais.<br/>
<br/>
Ensuite, il faut compiler un Qt statique, ce qui n'est pas bien compliqué. Assurez-vous d'avoir les binaires de MinGW dans le <span style="font-style: italic;">PATH</span>.<br/>
Les opérations à venir se passeront dans le dossier contienant Qt, disons <span style="font-style: italic;">C:\Qt\4.8.4</span>.<br/>
Éditez le fichier <span style="font-style: italic;">mkspecs\win32-g++\qmake.conf</span> et modifiez la ligne qui contient <span style="font-style: italic;">QMAKE_LFLAGS</span>&nbsp;:<br/>
<pre><code class="language-bash">QMAKE_LFLAGS = -static -static-libgcc</code></pre>
Puis dans une console, tapez&nbsp;:<br/>
<pre><code class="language-bash">> cd C:\Qt\4.8.4<br/>
> configure.exe -static -release -no-exceptions -opensource -nomake demos -nomake examples<br/>
> mingw32-make</code></pre>
Ceci prendra un bon moment, vous pouvez entamer la bière si ce n'est déjà fait.<br/>
Les arguments "<span style="font-style: italic;">-nomake demos -nomake examples</span>" sont optionnels, ils permettent de zapper la compilation des exemples et démos qui prennent un temps fou.<br/>
Il est possible d'activer/désactiver des fonctionnalités/plugins, essayez la commande&nbsp;:<br/>
<pre><code class="language-bash">> configure.exe help</code></pre>
<span style="color:gray;">Plus d'informations&nbsp;: <a href="http://www.qtcentre.org/wiki/index.php?title=Building_static_Qt_on_Windows">Building static Qt on Windows</a>.</span><br/>
<br/>
<hr />
<h2>Du côté du projet</h2>
<br/>
Vous êtes encore assez frais ? Bon, éditez le fichier .pro de votre projet et ajoutez cette ligne&nbsp;:<br/>
<pre><code class="language-bash">CONFIG += static</code></pre>
Compilez en mode <span style="font-style: italic;">release</span>... C'est terminé&nbsp;!<br/>
<br/>
<span style="color:gray;">Plus d'informations&nbsp;: <a href="http://qt.developpez.com/faq/?page=generalites-compilation#compilation-statique">Quand et comment réaliser une compilation "statique"?</a> et <a href="http://www.qtcentre.org/wiki/index.php?title=Building_static_applications">Building static applications</a>.</span>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130515224253
title: C++/Qt : i18n à l'international
uri: C-Qt-i18n-à-l-international
url: https://tiger-222.fr/?d=2013/05/15/22/42/53-cqt-i18n-a-linternational
content:
<h2>Du côté du développeur</h2>
<br/>
Le principe est relativement simple&nbsp;: Qt Creator va générer un fichier .ts que vous modifierez, puis il se chargera de le mettre dans le bon format pour votre application.<br/>
<br/>
Pour commencer, toutes les chaînes de caractères qui devront être traduites doivent être appelées à l'aide de la fonction <code class="inline">tr()</code>&nbsp;:<br/>
<pre><code class="language-c">QString texte = "Error while trying to save the configuration file:";<br/>
// doit être modifié tel que&nbsp;:<br/>
QString texte = tr("Error while trying to save the configuration file:");</code></pre>
<code class="language-c">tr()</code> (<a href="http://qt-project.org/doc/qt-4.8/i18n-source-translation.html">plus d'infos</a>) reçoit un argument obligatoire qui est la phrase ou le mot à traduire. Il est possible d'ajouter un second argument qui servira aux traducteurs pour spécifier le contexte ; par exemple pour expliquer les arguments ou s'il s'agit d'un bouton "Ok" ou du mot "Ok" pour dire "Ouais" ou "Oui" (mauvais exemple mais va falloir faire avec).<br/>
<br/>
Voici quelques exemples concrêts&nbsp;:<br/>
<pre><code class="language-c">tr("Error while trying to save the configuration file:");<br/>
tr("Done %1/100 ...").arg(percent);<br/>
tr("[%1] Done %2/100 ...", "Percent advancement: [file number] Done xx/100 ...").arg(file_number, percent);</code></pre>
On peut mettre autant de %1, %2, %3 que l'on souhaite, il s'agit de l'ordre des arguments donnés par arg().<br/>
<br/>
Vous aurez remarqué que j'ai mis les phrases en anglais, c'est pour ne pas avoir de surprises avec les accents sur les systèmes casse-couilles. Et puis de toute manière elles seront traduites par la suite&nbsp;:)<br/>
<br/>
Une fois toutes les phrases mises en évidence, il suffit de modifier le fichier <span style="font-weight: bold;">.pro</span> de votre projet et d'ajouter cette ligne tout en bas&nbsp;:<br/>
<pre><code class="language-bash">TRANSLATIONS = i18n/fr_FR.ts</code></pre>
Ceci veut dire que les fichiers de traduction (ici je n'ai mis que le français pure souche) seront placés dans le dossier <span style="font-style: italic;">i18n</span>. Il est possible de générer plusieurs fichiers de traduction&nbsp;:<br/>
<pre><code class="language-bash">TRANSLATIONS = i18n/fr_FR.ts i18n/fr_CA</code></pre>
Passons à la génération des fichiers, dans Qt Creator faîtes <code class="language-markup">Outils &gt; Externe &gt; Linguist</code> puis sélectionnez <code class="language-markup">Mettre à jour les traductions (lupdate)</code>. Si les fichiers n'existent pas, ils seront créés automatiquement.<br/>
<br/>
<hr />
<h2>Du côté des traducteurs</h2>
<br/>
Le principe est on ne peut plus simple&nbsp;! Les fichiers <span style="font-weight: bold;">.ts</span> sont de simple fichiers XML&nbsp;:<br/>
<pre><code class="language-markup">&lt;message>
	&lt;location filename="../mainwindow.ui" line="26"/><br/>
	&lt;source>Error while trying to save the configuration file:&lt;/source><br/>
	&lt;translation type="unfinished">&lt;/translation><br/>
&lt;/message></code></pre>
Il suffit d'envoyer le fichier .ts au traducteur qui, à l'aide d'un logiciel simplissime tel que Qt Linguist ou d'un simple traitement de texte tel que <a href="http://www.sublimetext.com/">Sublime Text</a>, <a href="http://www.geany.org/">Geany</a> ou encore <a href="http://www.scintilla.org/SciTE.html">SciTE</a>, n'aura qu'a entrer ses phrases traduites.<br/>
<br/>
Dans la ligne <code class="language-markup">translation</code> (dans le code plus haut), par défaut le type est <code class="language-markup">unfinished</code>, normal la phrase n'a pas été traduite. Il est possible de mettre <code class="language-markup">ignored</code>, comme ça l'application gardera la phrase originale. Lorsque la phrase est traduite, supprimez <code class="language-markup">type="unfinished"</code>.<br/>
<br/>
C'est tout, une fois terminé, le traducteur renvoie le fichier .ts au développeur. On y est presque ;)<br/>
<br/>
<hr />
<h2>Phase finale</h2>
<br/>
Dans Qt Creator faîtes <code class="language-markup">Outils &gt; Externe &gt; Linguist</code> puis sélectionnez <code class="language-markup">Publier les traductions (lrelease)</code>. De nouveaux fichiers sont créés&nbsp;: fr_FR.qm et fr_CA.qm.<br/>
Ce sont les fichiers finaux.<br/>
<br/>
La dernière étape consiste à mettre en place le système de traduction&nbsp;:<br/>
<pre><code class="language-c">int main(int argc, char *argv[])<br/>
{<br/>
    QApplication app(argc, argv);<br/>
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));  // ligne 4<br/>
<br/>
    QTranslator translator;<br/>
    translator.load(QString("%1/i18n/%2.qm")<br/>
            .arg(app.applicationDirPath())<br/>
            .arg(QLocale::system().name()));<br/>
    app.installTranslator(&translator);<br/>
<br/>
    MainWindow w;<br/>
    w.show();<br/>
    return app.exec();<br/>
}</code></pre>
<code class="language-c">load()</code> (<a href="http://qt-project.org/doc/qt-4.8/qtranslator.html#load">plus d'infos</a>) prend en 1er argument la locale du système (du genre fr_FR, fr_CA, en_US) et le 2ème (optionnel) le dossier dans lequel trouver les fichiers de traduction.<br/>
Notez la ligne 4&nbsp;: pour la prise en compte correcte des accent, elle est indispensable.<br/>
<br/>
Voilà&nbsp;! Exécutez votre application et admirez les jolies fautes d'ortographe&nbsp;:)<br/>
<br/>
<span style="color:gray;">Pour plus de détails&nbsp;: <a href="http://www.siteduzero.com/informatique/tutoriels/programmez-avec-le-langage-c/traduire-son-programme-avec-qt-linguist">Traduire son programme avec Qt Linguist </a>.</span>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130502023812
title: Clochette, Clochette !
uri: Clochette-Clochette
url: https://tiger-222.fr/?d=2013/05/02/02/38/12-clochette-clochette
content:
<h2 id="1">Un peu malgrè moi...</h2>
<br/>
Tout a commencé lors d'un voyage, lorsque ma soeur me ramena une clochette de Rome&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/85566a21.clochette-01.jpg" data-original-source="http://tiger-222.fr/img/clochette-01.jpg" alt="" /></div><br/>
C'est un cadeau pas cher et une collection comme une autre vous m'direz, que vous pourrez admirer sur cette superbe <span style="font-weight: bold;"><a href="http://tiger-222.fr/mappemonde/">mappemonde</a></span> (zoom de la <a href="http://tiger-222.fr/mappemonde/zoom/france/">France</a>). <span style="font-style: italic;">D'ailleurs, si vous être perdu quelque part sur la belle planète Terre, que vous voulez me faire une p'tite surprise, n'hésitez surtout pas&nbsp;:D</span><br/>
S'en sont suivies d'autres au fur et à mesure des différents voyages, accompagnées de quelques anecdotes (mise à jour en continu).<br/>
<br/>
<hr/>
<h2 id="2">Irelande&nbsp;: Dublin</h2>
<br/>
Quel est le comble du comble ? Visiter l'<a href="http://www.guinness-storehouse.com">usine Guinness</a>, pouvoir en goûter le précieux nectar gratuitement et... Décliner sagement. Il y a des claques qui se perdent&nbsp;!<br/>
<br/>
<div style="text-align:center;"><img src="media/cb3b47c9.clochette-02.jpg" data-original-source="http://tiger-222.fr/img/clochette-02.jpg" alt="" /></div><br/>
<hr/>
<h2 id="3">Îles Baléares&nbsp;: Majorque</h2>
<br/>
<div style="text-align:center;"><img src="media/c1f3a2f5.clochette-03.jpg" data-original-source="http://tiger-222.fr/img/clochette-03.jpg" alt="" /></div><br/>
<hr/>
<h2 id="4">Corée du sud&nbsp;: Séoul</h2>
<br/>
Quelle ville originale&nbsp;: lorsque le métro arrive, la musique de Rocky rententit, c'est énorme&nbsp;!<br/>
<br/>
<div style="text-align:center;"><img src="media/9a8bd04b.clochette-04.jpg" data-original-source="http://tiger-222.fr/img/clochette-04.jpg" alt="" /></div><br/>
<h2 id="5">Luxembourg&nbsp;: Luxembourg</h2>
<br/>
<div style="text-align:center;"><img src="media/211db165.clochette-05.jpg" data-original-source="http://tiger-222.fr/img/clochette-05.jpg" alt="" /></div><br/>
<hr/>
<h2 id="6">France&nbsp;: Lyon</h2>
<br/>
Bon, j'habite en France, et je n'avais pas de clochette du pays... C'est chose faite maintenant.<br/>
J'adore cette ville, dynamique, des beaux bâtiments, des scultures sympas et des moyens de transport <span style="font-style: italic;">à toute heure</span>&nbsp;: métro, tramway, bus ou encore Vélo'v. Mais surtout des endroits pour boire et se divertir. Si je devais vous conseiller, pour les fous tentez l'<a href="http://www.cityvox.fr/bars-et-cafes_lyon/l-abreuvoir_22950/Profil-Lieu">Abreuvoir</a>, et pour un super café théatre, il y a les <a href="http://tontonsflingueurs.com/">Tontons Flingueurs</a>&nbsp;: le personnel est accueillant [et charmant], les pièces jouées sont excellentes et l'ambiance générale est tout bonnement géniale. Il faut en abuser ;)<br/>
<br/>
<div style="text-align:center;"><img src="media/11cc7d65.clochette-06.jpg" data-original-source="http://tiger-222.fr/img/clochette-06.jpg" alt="" /></div><br/>
<hr/>
<h2 id="7">France&nbsp;: Annecy</h2>
<br/>
Une très belle clochette, une vraie de vraie, qui vient du <a href="http://www.paccard.com/">Musée de la Cloche Paccard</a>&nbsp;!<br/>
<br/>
<div style="text-align:center;"><img src="media/e1010c3e.clochette-07.jpg" data-original-source="http://tiger-222.fr/img/clochette-07.jpg" alt="" /></div><br/>
<hr/>
<h2 id="8">Allemagne&nbsp;: Munich</h2>
<br/>
Celle-ci est particulièrement jolie, avec le <a href="http://fetedelabiere.net/">bock de bière</a> pivotant au milieu.<br/>
<br/>
<div style="text-align:center;"><img src="media/da9c663f.clochette-08.jpg" data-original-source="http://tiger-222.fr/img/clochette-08.jpg" alt="" /></div><br/>
<hr/>
<h2 id="9">France&nbsp;: Gérarmer</h2>
<br/>
<div style="text-align:center;"><img src="media/07fccb12.clochette-09.jpg" data-original-source="http://tiger-222.fr/img/clochette-09.jpg" alt="" /></div><br/>
<hr/>
<h2 id="10">Thaïlande&nbsp;: Bangkok</h2>
<br/>
Et voici la clochette <span style="font-style: italic;">la plus kitsch de Bangkok</span>.<br/>
<br/>
<div style="text-align:center;"><img src="media/e2a97f32.clochette-10.jpg" data-original-source="http://tiger-222.fr/img/clochette-10.jpg" alt="" /></div><br/>
<hr/>
<h2 id="11">France&nbsp;: Strasbourg</h2>
<br/>
L'Alsace est dans la boîte&nbsp;!<br/>
<br/>
<div style="text-align:center;"><img src="media/c4d3ee12.clochette-11.jpg" data-original-source="http://tiger-222.fr/img/clochette-11.jpg" alt="" /></div>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130424025829
title: iPhone 3GS : jailbreak & desimlock
uri: iPhone-3GS-jailbreak-desimlock
url: https://tiger-222.fr/?d=2013/04/24/02/58/29-iphone-3gs-jailbreak-desimlock
content:
<div style="text-align:center;"><span style="font-weight: bold;"><span style="color:red;">/!\ Attention /!\<br/>
Je ne garantis rien dans cet article, ce que vous ferez sera de votre entière responsabilité.</span></span></div><br/>
<hr />
<h2>Le but de la manoeuvre</h2>
<br/>
Le but est de garder une trace pour le jailbreak et le desimlock de l'iPhone 3GS <span style="text-decoration: underline;">sous certaines conditions</span>.<br/>
Du coup, pour pouvoir suivre les manipulations à venir, il vous faudra impérativement&nbsp;:<br/>
<ul>
<li>un iPhone 3GS, forcément...</li>
<li>qu'il soit sous <span style="font-weight: bold;">iOS 5.0.1</span></li>
<li>que l'iPhone ait été fabriqué <span style="font-weight: bold;">avant</span> la 34ème semaine de 2011 (voir ci-après pour les détails)</li>
<li>être en <a href="https://fr.wikipedia.org/wiki/Baseband">baseband</a> <span style="font-weight: bold;">05.16.05</span> (voir ci-après pour les détails)</li>
<li>une connexion à Internet... ;)</li>
</ul>
Pour vérifier la date de fabrication de l'iPhone, il vous faut le numéro de série (dans <code class="language-markup">Réglages &gt; Général &gt; Informations</code>). Pour les fénéants, copier/coller l'adresse URL suivante (remplacer XXXXXXXXXXX par le numéro de série)&nbsp;:<br/>
<pre><code class="language-markup"><a href="http://www.powerbookmedic.com/identify-mac-serial.php?serial=XXXXXXXXXXX">http://www.powerbookmedic.com/identify-mac-serial.php?serial=XXXXXXXXXXX</a></code>
</pre>
<br/>
<div style="text-align:center;"><img src="media/1a680a30.iphone-3gs-dates.png" data-original-source="http://tiger-222.fr/img/iphone-3gs-dates.png" /></div><br/>
Ou sinon, sachez que le 3ème chiffre représente l'année (2010 = 0, 2011 = 1, 2012 = 2, ...) et les 4ème et 5ème la semaine. Donc si vous avez bien suivi, il ne faut pas que vos 3ème, 4ème et 5ème chiffres valent plus que... 134. Bien&nbsp;!<br/>
<br/>
Pour connaître le baseband, dans <code class="language-markup">Réglages &gt; Général &gt; Informations</code>, il s'agit en fait du <code class="language-markup">Prog. du modem</code>. Pas moyen de négocier avec d'autres baseband, il y a des tonnes de tutoriels à gauche à droite.<br/>
<br/>
<hr />
<h2>Avant tout</h2>
<br/>
Si vous en êtes là, ça veut dire que vous remplissez toutes les conditions pour passer aux choses sérieuses.<br/>
Il vous faut récupérer <a href="http://appldnld.apple.com/iPhone4/041-3307.20111109.5tGhu/iPhone2,1_5.0.1_9A405_Restore.ipsw">iOS 5.0.1</a> ainsi que le couteau suisse de l'iPhone, j'ai nommé <a href="http://blog.iphone-dev.org/">redsn0w</a>, la version <a href="https://sites.google.com/a/iphone-dev.com/files/home/redsn0w_win_0.9.15b3.zip">0.9.15b3</a> fera l'affaire.<br/>
<br/>
Voici la procédure, pour que ça soit clair pour tout le monde&nbsp;:<br/>
<ul>
<li>étape 1&nbsp;: jailbreak + MàJ du BB (celui de l'iPad&nbsp;: 06.15.00)</li>
<li>étape 2&nbsp;: revenir à une version plus ancienne du BB (05.13.04)</li>
<li>étape 3&nbsp;: finition du desimlock</li>
</ul>
<hr />
<h2>C'est parti mon kiki&nbsp;!</h2>
Pour un tutoriel tout en images, <a href="http://www.forum-iphone.fr/topic/51987-tuto-desimlocker-un-iphone-3gs-avec-le-baseband-051605051607/">c'est par ici</a>.<br/>
<br/>
<h3>Étape 1</h3>
<ul>
<li>éteindre l'iPhone, retirer la carte SIM et la brancher à l'ordinateur (fermer iTunes, s'il est ouvert)</li>
<li>lancer redsn0w <span style="font-weight: bold;">en mode Administrateur</span> puis <code class="language-markup">Extras &gt; Select IPSW</code> et sélectionner l'iOS téléchargé précédemment</li>
<li>faire <code class="language-markup">Back &gt; Jailbreak</code> et ne sélectionner que <code class="language-markup">Install Cydia</code> et <code class="language-markup">Install iPad baseband</code></li>
<li>faire <code class="language-markup">Next</code> et suivre les instructions pour passer en mode DFU</li>
<li>patienter... Le processus peut mettre un certain temps, des lignes s'afficheront sur l'écran de l'iPhone</li>
<li>quitter redsn0w</li>
</ul>
Une fois terminé, démarrer l'iPhone normalement et vérifier que l'application Cydia est bien installée et que le BB est en version 06.15.00, puis l'éteindre correctement. Nous avons fini l'étape 1&nbsp;!<br/>
<br/>
<h3>Étape 2</h3>
<ul>
<li>lancer redsn0w <span style="font-weight: bold;">en mode Administrateur</span> puis <code class="language-markup">Extras &gt; Select IPSW</code> et sélectionner l'iOS téléchargé précédemment</li>
<li>faire <code class="language-markup">Back &gt; Jailbreak</code> et ne sélectionner que <code class="language-markup">Downgrade from iPad baseband</code></li>
<li>faire <code class="language-markup">Next</code> et suivre les instructions pour passer en mode DFU</li>
<li>patienter... Le processus peut mettre un certain temps, des lignes s'afficheront sur l'écran de l'iPhone</li>
<li>quitter redsn0w</li>
</ul>
Une fois terminé, démarrer normalement l'iPhone et vérifier que le BB est bien en version 05.13.04 (si ce n'est pas le cas, recommencer l'étape 2). Nous avons fini l'étape 2&nbsp;!<br/>
<br/>
<h3>Étape 3</h3>
<ul>
<li>lancer Cydia et installer ultrasn0w</li>
<li>éteindre l'iPhone, insérer la carte SIM puis le démarrer</li>
<li>terminé bonsoir&nbsp;!</li>
</ul>
Nous avons fini l'étape 3&nbsp;!<br/>
Vous devriez avoir un iPhone jailbreaké et désimlocké&nbsp;:)


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130412145856
title: Combats épiques
uri: Combats-épiques
url: https://tiger-222.fr/?d=2013/04/12/14/58/56-combats-epiques
content:
<h2>Contexte</h2>
<br/>
Il y a des moments, dans un anime, où l'on peut voir que les traits de l'auteur(e) se font différents, paressant moins soignés. Ça rend super bien pour les combats intenses, afin de faire ressortir une sensation de grande vitesse et de fluidité dans les mouvements.<br/>
<br/>
<hr />
<h2>Preuves</h2>
<br/>
Par l'exemple, avec <a href="http://www.naruto-uzumaki.net/">Naruto</a>.<br/>
Le combat final qui oppose Naruto et Sasuke est particulièrement tendu&nbsp;:<br/>
<q>La bataille entre Naruto et Sasuke fait rage, les deux amis découvrent que ce sont leurs liens qui les rendent plus fort. Sasuke fait évoluer la forme de son sharingan et veut trancher ces liens qui le lient à Naruto. Mais ce dernier ne le laisse pas faire et se transforme, sous l'emprise de Kyûbi.</q><br/>
<div style="text-align:center;"><img src="media/864357db.combat-epique-1.jpg" data-original-source="http://tiger-222.fr/img/combat-epique-1.jpg" /><br/>
<span style="color:gray;">Le cri des larmes, tu es mon ami &#150; Saison 6 - Épisode 5 (n°133) &#150; <a href="http://tiger-222.fr/files/naruto-133.torrent">torrent</a></span><br/>
</div><br/>
<hr />
Un autre exemple, avec <a href="http://www.gaara-fr.com/">Naruto Shippûden</a>, lors de l'affrontement contre Pain&nbsp;:<br/>
<q>[Chapitres 437 à 439] &#150; Fou de rage, Naruto libère le chakra de Kyûbi sous la forme d'un démon à six queues et perd tout contrôle, affolant Yamato. Ne parvenant pas à prendre l’ascendant sur le bijū, Tendô utilise sa technique de «&nbsp;Naissance de l'astre divin&nbsp;» enfermant Naruto-Kyûbi dans une petite lune en altitude attirant une grande quantité de matière. Après avoir sorti deux queues de plus, Kyûbi demande à Naruto dans son subconscient d'enlever le sceau qui le retient ; alors que le jeune ninja s’apprête à s’exécuter, le 4e Hokage apparaît et l'en empêche…</q><br/>
<div style="text-align:center;"><img src="media/f88a9c48.combat-epique-2.jpg" data-original-source="http://tiger-222.fr/img/combat-epique-2.jpg" /><br/>
<span style="color:gray;">Naissance de l'astre divin &#150; Saison 7 - Épisode 14 (n°167) &#150; <a href="http://tiger-222.fr/files/naruto-shippuuden-167.torrent">torrent</a></span><br/>
</div><br/>
<hr />
<h2>Pour finir</h2>
<br/>
Voici deux liens qui mènent vers le Saint Graal des épisodes&nbsp;: <a href="https://fr.wikipedia.org/wiki/Liste_des_épisodes_de_Naruto">Naruto</a> et <a href="https://fr.wikipedia.org/wiki/Liste_des_épisodes_de_Naruto_Shippūden">Naruto Shippûden</a>.<br/>
Naruto est le seul anime (que j'ai vu) dans lequel on remarque une différence flagrante dans les dessins lors de combats intensifs. Cependant, si vous avez d'autres exemples, je serai ravi de mettre à jour cette page.<br/>
<br/>
<span style="text-decoration: underline;">Note</span>&nbsp;: si un jour <a href="http://jajatom.moo.jp/E-top/frame.html">Gunnm Last Order</a> est adapté en anime, je n'ose imaginer le résultat lorsque Gally (Yoko ou Alita c'est selon) et son équipe se battent lors du <abbr title="Zenith of Things Tournament">Z.O.T.T.</abbr>...<br/>
<div style="text-align:center;"><br/>
<img src="media/36f1a7e3.combat-epique-3.jpg" data-original-source="http://tiger-222.fr/img/combat-epique-3.jpg" /><br/>
<span style="color:gray;">Phase&nbsp;: 70&nbsp; Tu étais le seul au monde</span><br/>
</div>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130410125557
title: Le projet Tor Browser Bundle
uri: Le-projet-Tor-Browser-Bundle
url: https://tiger-222.fr/?d=2013/04/10/12/55/57-le-projet-tor-browser-bundle
content:
Je relaye l'info de <a href="http://neosting.net/logiciels/projet-lanceur-tor-browser-bundle-micah-lee.html">NeoSting.Net</a>, en ajoutant quelques détails.<br/>
<br/>
<h2>Installation</h2>
<br/>
J'ai du ajouter une dépendance (<span style="font-style: italic;">python-all</span>), la commande finale est donc&nbsp;:<br/>
<pre><code class="language-bash">$ aptitude install git python-stdeb python-gtk2 python-psutil python-twisted wmctrl gnupg python-all<br/>
$ git clone git://github.com/micahflee/torbrowser-launcher.git<br/>
$ cd torbrowser-launcher<br/>
$ ./build_and_install.sh</code></pre>
<br/>
<hr/>
<h2>Exécution</h2>
<br/>
J'ai constamment le message "SIGNATURE VERIFICATION FAILED!", en effet il cherche la signature mais il s'agit d'un fichier HTML&nbsp;:<br/>
<pre><code class="language-markup">&lt;!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
&lt;html>&lt;head><br/>
&lt;title>404 Not Found</title>
&lt;/head>&lt;body><br/>
&lt;h1>Not Found&lt;/h1><br/>
&lt;p>The requested URL /dist/torbrowser/linux/tor-browser-gnu-linux-x86_64-2.4.11-alpha-2-dev-fr.tar.gz.asc was not found on this server.&lt;/p><br/>
&lt;address>Apache Server at www.torproject.org Port 443&lt;/address><br/>
&lt;/body>&lt;/html></code></pre>
<br/>
Si l'on fouille un peu, on se rend compte que, sur sur le serveur, il n'y a que la version en-US qui est disponible&nbsp;:<br/>
<pre><code class="language-markup"><a href="https://www.torproject.org/dist/torbrowser/linux/">https://www.torproject.org/dist/torbrowser/linux/</a><br/>
  ...<br/>
  tor-browser-gnu-linux-x86_64-2.4.11-alpha-2-dev-en-US.tar.gz<br/>
  tor-browser-gnu-linux-x86_64-2.4.11-alpha-2-dev-en-US.tar.gz.asc<br/>
  ...</code></pre>
Pas grave, pour ceux qui veulent absolument la dernière mise à jour, il suffit de modifier la ligne 194 du fichier <span style="text-decoration: underline;">torbrowser-launcher</span> tel que <code class="language-markup">default_locale = 'en-US'</code>.<br/>
<br/>
Le dernière mise à jour est récupérée et le panneau de contrôle <a href="https://www.torproject.org/projects/vidalia.html.en">Vidalia</a> s'affiche ainsi que le navigateur sécurisé/anonyme&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/0948d5c2.vidalia.png" data-original-source="http://tiger-222.fr/img/vidalia.png" /><br/>
<span style="color:gray;">Épurée et efficace comme je les aime&nbsp;!</span></div><br/>
<hr/>
<h2>Configuration</h2>
<br/>
Pour mettre l'interface en français, cliquer sur <span style="font-style: italic;">Settings</span> puis, dans l'onglet <span style="font-style: italic;">Appearance</span>, sélectionner <span style="text-decoration: underline;">français</span> dans la liste déroulante en dessous de <span style="font-style: italic;">Language</span>.<br/>
<br/>
Ensuite, si vous voulez apporter votre contribution au projet, dans l'onglet Partage, vous pouvez configurer votre relais Tor.<br/>
Comme c'est bien décrit dans l'aide, je la cite, mais vous devrier y jeter un oeil c'est bien expliqué&nbsp;:<br/>
<q>Le réseau Tor est constitué par des bénévoles du monde entier qui donnent une partie de leur bande passante perdue en installant un relais Tor. Vidalia vous aide à participer au réseau Tor en facilitant l'installation de votre propre relais.<br/>
</q><br/>
Ça ne mange pas de pain et vous aurez fait une bonne action.


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130409134501
title: andLess
uri: andLess
url: https://tiger-222.fr/?d=2013/04/09/13/45/01-andless
content:
<span style="font-weight: bold;">Après quelques recherches...</span><br/>
Et moultes essais, j'ai enfin trouvé le lecteur de musique qu'il me fallait pour Android&nbsp;: <a href="https://code.google.com/p/andless/">andLess</a>&nbsp;!<br/>
Simple et efficace, il est léger (652Kio une fois installé) et reconnaît tous les formats natifs ainsi que le FLAC et d'autres conteneurs sans pertes.<br/>
<br/>
En prime, voilà deux captures d'écran&nbsp;:<br/>
<div style="text-align:center;"><img src="media/99cc2158.andless.jpg" data-original-source="https://tiger-222.fr/img/andless.jpg" /></div>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130409132855
title: Factorisation - P and Q
uri: Factorisation-P-and-Q
url: https://tiger-222.fr/?d=2013/04/09/13/28/55-factorisation---p-and-q
content:
Le but est de déchiffrer le mot de passe de validation.<br/>
Voici la clef utilisée&nbsp;: <a href="http://tiger-222.fr/files/ch6.zip">ch6.zip</a>, ainsi que le texte chiffré&nbsp;:<br/>
<pre><code class="language-markup">e8oQDihsmkvjT3sZe+EE8lwNvBEsFegYF6+OOFOiR6gMtMZxxba/bIgLUD8pV3yEf0gOOfHuB5bC3vQmo7bE4PcIKfpFGZBA</code></pre>
<br/>
<hr />
<h2>Récupérer N et e</h2>
<br/>
<pre><code class="language-bash">$ openssl rsa -in pubkey.pem -pubin -text -modulus<br/>
Public-Key: (576 bit)<br/>
Modulus:<br/>
00:c2:cb:b2:4f:db:f9:23:b6:12:68:e3:f1:1a:38:<br/>
96:de:45:74:b3:ba:58:73:0c:bd:65:29:38:86:4e:<br/>
22:23:ee:eb:70:4a:17:cf:d0:8d:16:b4:68:91:a6:<br/>
14:74:75:99:39:c6:e4:9a:af:e7:f2:59:55:48:c7:<br/>
4c:1d:7f:b8:d2:4c:d1:5c:b2:3b:4c:d0:a3<br/>
Exponent: 65537 (0x10001)<br/>
Modulus=C2CBB24FDBF923B61268E3F11A3896DE4574B3BA58730CBD652938864E2223EEEB704A17CFD08D16B46891A61474759939C6E49AAFE7F2595548C74C1D7FB8D24CD15CB23B4CD0A3<br/>
writing RSA key<br/>
-----BEGIN PUBLIC KEY-----<br/>
MGQwDQYJKoZIhvcNAQEBBQADUwAwUAJJAMLLsk/b+SO2Emjj8Ro4lt5FdLO6WHMMvW<br/>
UpOIZOIiPu63BKF8/QjRa0aJGmFHR1mTnG5Jqv5/JZVUjHTB1/uNJM0VyyO0zQowIDAQAB<br/>
-----END PUBLIC KEY-----</code></pre>
Conversion héxa =&gt; décimale&nbsp;:<br/>
<pre><code class="language-bash">$ python -c "print int('valeur_Modulus', 16)"</code></pre>
Nous avons donc&nbsp;:<br/>
<span style="font-style: italic;">N</span> =<br/>
188198812920607963838697239461650439807163563379417382700763356422988859715234665485319060606504743045317388011303396716199692321205734031879550656996221305168759307650257059<br/>
<span style="font-style: italic;">e</span> = 65537<br/>
<br/>
<hr />
<h2>Déterminer les facteurs p et q</h2>
<br/>
Le site <a href="http://www.factordb.com/">factordb</a> permet de les trouver facilement.<br/>
<pre><code class="language-markup"><a href="http://www.factordb.com/index.php?query=valeur_N">http://www.factordb.com/index.php?query=valeur_N</a></code></pre>
Nous trouvons donc&nbsp;:<br/>
<span style="font-style: italic;">p</span> = 398075086424064937397125500550386491199064362342526708406385189575946388957261768583317<br/>
<span style="font-style: italic;">q</span> = 472772146107435302536223071973048224632914695302097116459852171130520711256363590397527<br/>
<br/>
<hr />
<h2>Trouver d</h2>
<br/>
Voici le code de <a href="https://raw.github.com/ius/rsatool/master/rsatool.py">rsatool.py</a>.<br/>
Dans le code suivant, par soucis de clarté je ne renseigne pas les valeurs de p, q ni N.<br/>
<pre><code class="language-bash">$ python rsatool.py -p valeur_p -q valeur_q -n valeur_N -e valeur_e<br/>
Using (p, q) to initialise RSA instance<br/>
d = 32030e42c69d4e77de7e2397b13dba2e52f2c57a205f5973fed6f87632f53cf8886609ff63fa114e2b5df1db6249f8eaf0bf5fa26ad5b8e48b7fab050d32fc574b446e22d08ba7b1</code></pre>
Conversion héxa =&gt; décimale&nbsp;:<br/>
<pre><code class="language-bash">$ python -c "print int('valeur_d', 16)"</code></pre>
Enfin, <span style="font-style: italic;">d</span> = <br/>
48318251158920145864930035723053089097690375168562443830554407970661009102774592695057202204701378327623682075089028698815133956650193819978456750305738325912711134934968241<br/>
<br/>
<hr />
<h2>Final</h2>
<br/>
La solution finale peut-être trouvée à l'aide du module rsa (<code class="inline">pip install rsa</code>)&nbsp;:<br/>
<pre><code class="language-python">import rsa<br/>
pk = rsa.PrivateKey(N, e, d, p, q)<br/>
import base64<br/>
rsa.decrypt(base64.b64decode(ciphertext), pk)</code></pre>
<pre><code class="language-python">>>> Hop, le mot de passe de validation est "*****".</code></pre>
<br/>
<span style="color:gray;">Sources diverses&nbsp;: <a href="http://www.infond.fr/2012/05/w3challs-rsa.html">infond</a>, <a href="http://m0x39.blogspot.fr/2012/12/0x00-introduction-this-post-is-going-to.html">m0x39.blogspot</a> et <a href="http://stuvel.eu/files/python-rsa-doc/reference.html#rsa.PrivateKey">doc python</a>.</span>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130409131047
title: ELF - Random Crackme
uri: ELF-Random-Crackme
url: https://tiger-222.fr/?d=2013/04/09/13/10/47-elf---random-crackme
content:
Le <a href="http://www.root-me.org/fr/Challenges/Cracking/ELF-Random-Crackme">challenge</a> consiste à donner le bon mot de passe. Le fichier<a href="https://tiger-222.fr/files/ch5.zip"> ch5.zip</a> est fourni.<br/>
<hr />
<h2>Étape 1</h2>
<br/>
Décompresser l'archive... Facile&nbsp;!<br/>
On se retrouve avec un fichier nommé crackme_wtf.<br/>
<br/>
<hr />
<h2>Étape 2</h2>
<br/>
<span style="color:purple;">MàJ&nbsp;: il suffit de faire un "<span style="font-style: italic;">ar -x crackme_wtf</span>" pour décompresser le fichier.<br/>
Tu peux sauter cette étape.</span><br/>
<br/>
Sous Debian GNU/Linux, ce fichier a l'icône d'une archive, cependant, pas moyen d'en faire quelques chose.<br/>
La commande <code class="language-bash">file</code> renvoie&nbsp;:<br/>
<pre><code class="language-bash">$ file crackme_wtf<br/>
crackme_wtf: current ar archive</code></pre>
Bon, voyons à l'aide d'un éditeur héxadécimal ce que donnent les 8 premiers octets&nbsp;:<br/>
<pre><code class="language-bash">$ hexdump -n 8 -C crackme_wtf<br/>
00000000  21 3c 61 72 63 68 3e 0a  |!&lt;arch>.|</code></pre>
Mouai... À tout hasard, l'excellent <a href="https://bitbucket.org/haypo/hachoir/wiki/hachoir-subfile">hachoir-subfile</a> saura peut-être m'en dire plus.<br/>
<q>(hachoir-subfile) L'idée est d'extraire des fichiers (non compressés, non chiffrés et non fragmentés) contenus dans d'autres fichier &#150; <a href="http://www.haypocalc.com/wiki/Accueil">Victor STINNER</a>.<br/>
</q><br/>
<pre><code class="language-bash">$ hachoir-subfile crackme_wtf<br/>
[+] Start search on 14418 bytes (14.1 KB)<br/>
[+] File at 0: Unix archive<br/>
[+] File at 424: ELF Unix/BSD program/library: 32 bits<br/>
[+] End of search -- offset=14418 (14.1 KB)</code></pre>
Hop hop&nbsp;! Que vois-je ? À l'offset 424 il y aurait un binaire ELF ? Ok, <code class="language-bash">tail</code> est notre ami&nbsp;:<br/>
<pre><code class="language-bash">$ tail --bytes=+425 crackme_wtf >Crackme<br/>
$ file Crackme<br/>
chal: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped<br/>
$ ldd Crackme <br/>
	linux-gate.so.1 =>  (0xf7736000)<br/>
	libc.so.6 => /lib32/libc.so.6 (0xf75b3000)<br/>
	/lib/ld-linux.so.2 (0xf7737000)<br/>
$ chmod +x Crackme<br/>
$ ./Crackme<br/>
    ** Bienvenue dans ce challenge de cracking **    <br/>
[+] Password&nbsp;:azerty<br/>
[!]Access Denied&nbsp;!  <br/>
[-] Try again</code></pre>
L'exécutable est lié dynamiquement aux bibliothèques, ce qui sera intéressant par la suite.<br/>
<br/>
<hr />
<h2>Étape 3</h2>
<br/>
Nous avons enfin l'exécutable, voyons ce qu'on peut en faire.<br/>
<pre><code class="language-bash">$ strings Crackme<br/>
/lib/ld-linux.so.2<br/>
__gmon_start__<br/>
libc.so.6<br/>
_IO_stdin_used<br/>
exit<br/>
sprintf<br/>
srand<br/>
puts<br/>
time<br/>
__stack_chk_fail<br/>
stdin<br/>
getpid<br/>
fgets<br/>
strlen<br/>
memset<br/>
getchar<br/>
__errno_location<br/>
fputc<br/>
malloc<br/>
stderr<br/>
ptrace<br/>
fwrite<br/>
strchr<br/>
strcmp<br/>
__libc_start_main<br/>
free<br/>
GLIBC_2.4<br/>
GLIBC_2.0<br/>
PTRh<br/>
VTEP<br/>
IQAV<br/>
Y[_]<br/>
[^_]<br/>
_VQLGE_TQPTYD_KJTIV_<br/>
%lld%s<br/>
[-] Allocation memoire echouee!<br/>
[-]Debugger detecte ... Exit<br/>
    ** Bienvenue dans ce challenge de cracking **    <br/>
[+] Password&nbsp;:<br/>
[!]Access Denied&nbsp;!  <br/>
[-] Try again <br/>
[+]Good password  <br/>
[+] Clee de validation du crack-me&nbsp;: <br/>
%d_%s%d_</code></pre>
Il y a une protection anti-debugger apparemment et quelques appels à des fonctions qui peuvent être intéressantes telles que <code class="language-c">strcmp</code>, <code class="language-c">strlen</code> ou même <code class="language-c">strchr</code>.<br/>
<br/>
Je tente quand même d'ouvrir le binaire dans un débugger&nbsp;:<br/>
<pre><code class="language-bash">$ gdb Crackme            <br/>
# (...)<br/>
Reading symbols from /home/tiger-222/chal...done.<br/>
(gdb) run<br/>
Starting program: /home/tiger-222/chal <br/>
[-]Debugger detecte ... Exit<br/>
[Inferior 1 (process 6523) exited with code 01]<br/>
(gdb) quit<br/>
<br/>
$ strace ./Crackme<br/>
(...)<br/>
write(2, "[-]Debugger detecte ... Exit\n", 29[-]Debugger detecte ... Exit<br/>
(...)</code></pre>
Comme il fallait s'y attendre, <code class="language-bash">gdb</code> et <code class="language-bash">strace</code> ne fonctionnent pas. J'opte pour l'usurpation (hook) de la fonction <code class="language-c">strcmp</code>.<br/>
<br/>
<hr />
<h2>Étape 4</h2>
Alors, l'usurpation, comment ça se passe ?<br/>
Et bien il y a une variable d'environnement sous le doux nom de <span style="font-style: italic;">LD_PRELOAD</span> qui sert à charger ses propres bibliothèques de fonction. Je vais m'en servir pour dire au programme de prendre la mienne plutôt que celle du système.<br/>
<br/>
Voici le code pour hook_strcmp.c&nbsp;:<br/>
<pre><code class="language-c">#define _GNU_SOURCE<br/>
#include &lt;stdio.h>
#include &lt;dlfcn.h><br/>
<br/>
int strcmp(const char *str1, const char *str2) {<br/>
	printf("[Hook strcmp] str1 = %s\n", str1);<br/>
	printf("              str2 = %s\n", str2);<br/>
<br/>
	// Appel de la véritable fonction<br/>
	typeof(strcmp)* function;<br/>
	function = dlsym(RTLD_NEXT, "strcmp");<br/>
	return (*function)(str1, str2);<br/>
}</code></pre>
Que l'on compile tel que&nbsp;:<br/>
<pre><code class="language-bash">$ gcc -Wall -fPIC -c -o hook_strcmp.o hook_strcmp.c<br/>
hook_strcmp.c:5:5: warning: conflicting types for built-in function ‘strcmp’ [enabled by default]<br/>
$ gcc -shared -fPIC -Wl,-soname -Wl,hook_strcmp.so -ldl -o /tmp/hook_strcmp.so hook_strcmp.o</code></pre>
L'erreur, c'est normal, le compilo nous informe officiellement que notre fonction est en conflit avec celle du système, tiens donc&nbsp;!<br/>
Pour trouver le prototype d'une fonction, va faire un tour sur ce <a href="http://www.cplusplus.com/reference/cstring/strcmp/">site</a>.<br/>
<br/>
Nous avons donc notre bibliothèque perso, voyons ce que ça donne&nbsp;:<br/>
<pre><code class="language-bash">$ export LD_PRELOAD="/tmp/hook_strcmp.so"<br/>
$ ./Crackme <br/>
<br/>
    ** Bienvenue dans ce challenge de cracking **    <br/>
<br/>
[+] Password&nbsp;:azerty<br/>
[Hook strcmp] str1 = azerty<br/>
              str2 = 235625580_VQLGE_TQPTYD_KJTIV_<br/>
<br/>
[!]Access Denied&nbsp;!  <br/>
[-] Try again</code></pre>
Ah&nbsp;! C'est un début prometteur&nbsp;!<br/>
<br/>
Testons <span style="font-style: italic;">str2</span>&nbsp;:<br/>
<pre><code class="language-bash">$ ./Crackme<br/>
<br/>
    ** Bienvenue dans ce challenge de cracking **    <br/>
<br/>
[+] Password&nbsp;:235625580_VQLGE_TQPTYD_KJTIV_<br/>
[Hook strcmp] str1 = 235625580_VQLGE_TQPTYD_KJTIV_<br/>
              str2 = 139734408_VQLGE_TQPTYD_KJTIV_<br/>
<br/>
[!]Access Denied&nbsp;!  <br/>
[-] Try again</code></pre>
Maintenant c'est clair, le mot de passe est constitué d'un nombre qui semble aléatoire suivi de la chaîne _VQLGE_TQPTYD_KJTIV_.<br/>
<br/>
Tout à l'heure, la commande <span style="font-style: italic;">strings</span> nous a renvoyé d'autres noms de fonctions utilses pour le pseudo-aléatoire tel que <code class="language-c">srand</code>,  <code class="language-c">rand</code> et  <code class="language-c">time</code>. Notons aussi  <code class="language-c">getpid()</code>, il arrive que le <a href="https://fr.wikipedia.org/wiki/Identifiant_de_processus">pid</a> soit ajouté comme sel.<br/>
<br/>
C'est parti pour de l'usurpation de bourin, hook_multi.c&nbsp;:<br/>
<pre><code class="language-c">#define _GNU_SOURCE<br/>
#include &lt;stdio.h>
#include &lt;dlfcn.h><br/>
<br/>
int strcmp(const char *str1, const char *str2) {<br/>
	printf("[Hook strcmp] str1 = %s\n", str1);<br/>
	printf("              str2 = %s\n", str2);<br/>
<br/>
	// Appel de la véritable fonction<br/>
	typeof(strcmp)* function;<br/>
	function = dlsym(RTLD_NEXT, "strcmp");<br/>
	return (*function)(str1, str2);<br/>
}<br/>
<br/>
int getpid() { printf("[Hook getpid] 0\n"); return 0; }<br/>
int srand()  { printf("[Hook srand] 0\n");  return 0; }<br/>
int time()   { printf("[Hook time] 0\n");   return 0; }</code></pre>
Tout le monde renverra 0, comme ça pas de chichi, si le programme souhaite un nombre pseudo-aléatoire entre 0 et 0, ça restreint les possibilités&nbsp;!<br/>
<br/>
Testons&nbsp;:<br/>
<pre><code class="language-bash">$ gcc -Wall -fPIC -c -o hook_multi.o hook_multi.c<br/>
hook_strcmp.c:5:5: warning: conflicting types for built-in function ‘strcmp’ [enabled by default]<br/>
$ gcc -shared -fPIC -Wl,-soname -Wl,hook_multi.so -ldl -o /tmp/hook_multi.so hook_multi.o <br/>
$ export LD_PRELOAD="/tmp/hook_multi.so"<br/>
$ ./Crackme<br/>
[Hook time] 0<br/>
[Hook srand] 0<br/>
[Hook getpid] 0<br/>
[Hook srand] 0<br/>
[-]Debugger detecte ... Exit</code></pre>
Arf&nbsp;! Pas bon ça&nbsp;!<br/>
Les usurpations de <code class="language-c">time</code>, <code class="language-c">srand</code> et <code class="language-c">getpid</code> semblent fonctionner, je supprime celle de <code class="language-c">rand</code>... Ça fonctionne. Vilain petit canard&nbsp;!<br/>
<br/>
Résultat&nbsp;:<br/>
<pre><code class="language-bash">$ export LD_PRELOAD="/tmp/hook_multi.so"<br/>
$ ./Crackme<br/>
[Hook time] 0<br/>
[Hook srand] 0<br/>
[Hook getpid] 0<br/>
<br/>
    ** Bienvenue dans ce challenge de cracking **    <br/>
<br/>
[+] Password&nbsp;:azerty<br/>
[Hook strcmp] str1 = azerty<br/>
              str2 = 0_VQLGE_TQPTYD_KJTIV_<br/>
<br/>
[!]Access Denied&nbsp;!  <br/>
[-] Try again</code></pre>
<br/>
Je réessaie 3-4 fois et <span style="font-style: italic;">str2</span> vaut toujours la même chose, je l'entre comme mot de passe et.. TADAAA&nbsp;!!<br/>
<pre><code class="language-bash">$ ./Crackme<br/>
[Hook time] 0<br/>
[Hook srand] 0<br/>
[Hook getpid] 0<br/>
<br/>
    ** Bienvenue dans ce challenge de cracking **    <br/>
<br/>
[+] Password&nbsp;:0_VQLGE_TQPTYD_KJTIV_<br/>
[Hook strcmp] str1 = 0_VQLGE_TQPTYD_KJTIV_<br/>
              str2 = 0_VQLGE_TQPTYD_KJTIV_<br/>
<br/>
[+]Good password  <br/>
[+] Clee de validation du crack-me&nbsp;: *****</code></pre>
Bon je cache quand même le mot de passe pour ne pas te mâcher tout le travail.<br/>
<br/>
<span style="color:gray;">Je me suis inspiré de cette <a href="http://fluxius.handgrep.se/2011/10/31/the-magic-of-ld_preload-for-userland-rootkits/">source</a>.</span>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130409130517
title: Cracker le schéma de vérouillage d'Android
uri: Cracker-le-schéma-de-vérouillage-d-Android
url: https://tiger-222.fr/?d=2013/04/09/13/05/17-cracker-le-schema-de-verouillage-dandroid
content:
Le fichier contenant les informations se trouve dans <span style="font-style: italic;">/data/system/gesture.key</span>.<br/>
Il s'agit du condensat SHA1 de la combinaison...<br/>
<hr />
<h2>Récupérer le fichier</h2>
<br/>
Une façon de l'obtenir est d'utiliser <a href="https://developer.android.com/tools/help/adb.html">adb</a>&nbsp;:<br/>
<pre><code class="language-bash">$ adb pull /data/system/gesture.key .</code></pre>
<br/>
<hr />
<h2>Méthode 1</h2>
<br/>
Récupération du fichier qui contient la <a href="https://fr.wikipedia.org/wiki/Table_arc-en-ciel">rainbow table</a>&nbsp;:<br/>
<pre><code class="language-bash">$ wget www.android-forensics.com/tools/AndroidGestureSHA1.rar<br/>
$ unrar -x AndroidGestureSHA1.rar<br/>
$ rm AndroidGestureSHA1.rar</code></pre>
Pour rechercher une combinaison&nbsp;:<br/>
<pre><code class="language-bash">$ grep $(hexdump -e '1/1 "%.2X"' gesture.key) AndroidGestureSHA1.txt<br/>
32158;02 01 00 04 07;DAC5E906A26D0903C518E51DAACB15CE064E7603</code></pre>
Ici, la combinaison sera donc 3 > 2 > 1 > 5 > 8.<br/>
<br/>
<hr />
<h2>Méthode 2</h2>
<br/>
<a href="http://thanat0s.trollprod.org/2013/07/lock-pattern-et-android/">ThаnатøS Пещеру</a> explique comme faire en passant par <a href="http://hashcat.net/hashcat/">Hashcat</a>.<br/>
<br/>
<hr />
<h2>Méthode 3</h2>
<br/>
De loin la plus <span style="font-style: italic;">olé olé</span>, mais qui peut s'avérer payante&nbsp;: tenter de déviner la combinaison grâce aux traces de doigts sur l'écran&nbsp;!


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130409125904
title: Les failles du oueb
uri: Les-failles-du-oueb
url: https://tiger-222.fr/?d=2013/04/09/12/59/04-les-failles-du-oueb
content:
<h2>Les failles qui hantent la toile</h2>
<br/>
<ul>
<li><a href="https://fr.wikipedia.org/wiki/CSRF">Cross-site request forgery ou CSRF</a> => <a href="http://www.experience-developpement.fr/jouez-le-jeton-de-la-securite/">comprendre et s'en protéger</a></li>
<li><a href="https://fr.wikipedia.org/wiki/Cross-site_scripting">Cross-site scripting ou XSS</a> => <a href="http://www.experience-developpement.fr/securite-protection-faille-xss/">comprendre et s'en protéger</a></li>
<li><a href="https://fr.wikipedia.org/wiki/Injection_SQL">Injection SQL</a> => <a href="http://www.experience-developpement.fr/php-pdo-requetes-preparees/">comprendre et s'en protéger</a></li>
</ul>
<hr />
<h2>Chiffrement des mots de passe</h2>
<br/>
Il faut oublier <a href="http://www.php.net/manual/fr/faq.passwords.php#faq.passwords.fasthash">MD5 et autres SHA1</a>, et passer à du lourd comme l'algorithme <a href="http://www.php.net/manual/fr/function.crypt.php">Blowfish</a>&nbsp;:<br/>
<pre><code class="language-php">&lt;?php<br/>
<br/>
// Créer le mot de passe<br/>
(string)$sel  = substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 22);<br/>
(string)$hash = crypt('mot de passe', '$2x$11$'.$sel);<br/>
<br/>
// Vérifier un mot de passe<br/>
if ( crypt($_POST['mot_de_passe'], $hash) === $hash ) {<br/>
	// Mot de passe correct&nbsp;!<br/>
}<br/>
<br/>
?></code></pre>
Le sel passé à la fonction <a href="http://php.net/manual/fr/function.crypt.php">crypt</a> est formé tel que <span style="font-style: italic;">&lt;algorithme>&lt;itérations>$&lt;sel></span> où&nbsp;:<br/>
<br/>
<ul>
<li>&lt;algorithme>&nbsp;: vaut $2x$ ou $2y$ si disponible (<a href="http://www.php.net/security/crypt_blowfish.php">éviter d'utiliser $2a$</a>)</li>
<li>&lt;itérations>&nbsp;: compris en 04 et 31, il s'agit du nombre d'itérations (compléxité), plus il est proche de 31, mieux c'est, mais de beaucoup de patience t'armer il faudra</li>
<li>&lt;sel>&nbsp;: chaîne de 22 caractères compris dans l'alphabet [./0-9A-Za-z]</li>
</ul>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130405161653
title: Télécommunications et sécurité
uri: Télécommunications-et-sécurité
url: https://tiger-222.fr/?d=2013/04/05/16/16/53-telecommunications-et-securite
content:
<h2>Contexte</h2>
<q><span style="font-weight: bold;">Julian</span>&nbsp;: Andy, tu as passé des années à concevoir des téléphones cryptographique. Quel type de surveillance de masse est en cours dans les télécommunications ? Dis moi quel est le travail de pointe en ce qui concerne le renseignement d'État et l'industrie de la surveillance de masse ?<br/>
<span style="font-weight: bold;">Andy</span>&nbsp;: C'est le stockage de masse &#150; c'est-à-dire qu'on stocke toutes les télécommunications, tous les appels vocaux, toutes les données de trafic, tous les usages de Short Message Service (SMS), mais aussi les connexions Internet, et dans certaines stations au moins les mails.<br/>
</q><br/>
Le passage est tiré du chapitre "Militarisation du cyberespace", pages 52 et 53, du livre <span style="text-decoration: underline;">Menaces sur nos libertés</span>, paru en février 2013, publié par Julian Assange (fondateur de <a href="http://wikileaks.org/">Wikileaks</a>), co-écrit avec le français Jérémie Zimmerman (membre de l'association <a href="http://www.laquadrature.net/">La Quadrature du Net</a>), l'américain Jacob Appelbaum (à l'origine du projet <a href="https://www.torproject.org/">Tor</a>) et le spécialiste en cryptage allemand Andy Müller-Maguhn (membre du <a href="http://www.ccc.de/">Chaos Computer Club</a>).<br/>
C'est un livre très intéressant &laquo; à mettre entre toutes les mains &raquo;, je vous le conseille vivement. <a href="http://www.readiware.com/livre-culture-societe/livre-sciences-humaines/menace-sur-nos-libertes-comment-internet-nous-espionne-comment-resister/">Achetez-le</a> ou <span style="font-size:9pt;"><a href="https://kat.ph/cypherpunks-fr-menaces-sur-nos-libert%C3%A9s-epub-fr-t7228317.html">téléchargez-le</a></span>.<br/>
<br/>
De plus, voici quelques documents intéressants à lire (mise à jour en continu)&nbsp;:<br/>
<ul>
<li>2010-08-12&nbsp;: <a href="media/2642f651.cellular-spy.pdf" data-original-source="http://tiger-222.fr/files/cellular-spy.pdf">Rétention de données des opérateurs de téléphonie mobile aux USA (1)</a> (<a href="http://cryptome.org/">Cryptome</a>)</li>
<li>2011-03-15&nbsp;: <a href="media/f46c995e.cellular-spy2.pdf" data-original-source="http://tiger-222.fr/files/cellular-spy2.pdf">Rétention de données des opérateurs de téléphonie mobile aux USA (2)</a> (<a href="http://cryptome.org/">Cryptome</a>)</li>
<li>2013-04-13&nbsp;: <a href="http://www.wired.com/threatlevel/2013/04/verizon-rigmaiden-aircard/all/">Secrets of FBI Smartphone Surveillance Tool Revealed in Court Fight</a></li>
<li>2013-04-18&nbsp;: <a href="http://www.businessinsider.com/congress-passes-cispa-cybersecurity-bill-2013-4">The House Just Passed The CISPA Cybersecurity Bill</a></li>
<li>2013-04-22&nbsp;: <a href="http://www.wikistrike.com/article-septembre-2013-le-gigantesque-centre-d-espionnage-de-la-nsa-sera-operationnel-117278484.html">Septembre 2013: le gigantesque centre d'espionnage de la NSA sera opérationnel</a></li>
<li>2013-04-22&nbsp;: <a href="http://www.developpez.com/actu/54447/Apple-revele-qu-il-stocke-les-donnees-vocales-pendant-deux-ans-pour-les-applications-Siri-et-Dictation/">Apple révèle qu'il stocke les données vocales pendant deux ans pour les applications Siri et Dictation</a></li>
<li>2013-05-05&nbsp;: <a href="http://bluetouff.com/2013/05/05/affaire-tsarnaev-la-surveillance-de-masse-des-citoyens-americains-revelee-par-un-ex-agent-du-fbi/">Affaire Tsarnaev&nbsp;: la surveillance de masse des citoyens américains révélée par un ex-agent du FBI</a></li>
<li>2013-05-07&nbsp;: <a href="http://lexpansion.lexpress.fr/high-tech/internet-sms-comment-thales-va-mettre-les-reseaux-francais-sur-ecoute_383757.html">Internet, SMS&nbsp;: comment Thales va mettre les réseaux français sur écoute</a></li>
<li>2013-05-12&nbsp;: <a href="http://boingboing.net/2013/05/12/apple-can-decrypt-iphones-for.html">Apple can decrypt iPhones for cops; Google can remotely "reset password" for Android devices</a></li>
<li>2013-05-13&nbsp;: <a href="http://www.wired.com/threatlevel/2013/05/doj-got-reporter-phone-records/">Obama Administration Secretly Obtains Phone Records of AP Journalists</a></li>
<li>2013-06-05&nbsp;: <a href="https://www.eff.org/deeplinks/2013/06/confirmed-nsa-spying-millions-americans">Confirmed: The NSA is Spying on Millions of Americans</a></li>
<li>2013-06-12&nbsp;: <a href="http://bluetouff.com/2013/06/12/prism-pourquoi-ce-pseudo-scandale-men-touche-une-sans-faire-bouger-lautre/">#Prism&nbsp;: pourquoi ce pseudo scandale m’en touche une sans faire bouger l’autre ?</a></li>
<li>2013-06-30&nbsp;: <a href="http://www.beneaththewaves.net/Projects/Motorola_Is_Listening.html">Motorola Is Listening</a></li>
<li>2013-07-04&nbsp;: <a href="http://korben.info/infrastructure-de-mutualisation.html">Infrastructure de mutualisation</a></li>
</ul>
<hr />
<h2>Se protéger</h2>
<br/>
Je vous ai bien effrayé... Mais y a t-il un moyen de rendre nos communications confidentielles ? Je veux dire par là que ce sont des informations qui m'appartiennent à moi seul(e) et à mon interlocuteur&nbsp;!<br/>
Le réponse est, grâce à de brillants hackers/chercheurs/passionnés, <span style="font-weight: bold;">oui</span>.<br/>
<br/>
Pour commencer, il y a le <a href="http://www.cryptophone.de/">Cryptophone</a>, il s'agit d'un téléphone mobile basique avec une grosse couche sécurité par dessus.<br/>
En clair, tout message (SMS, MMS) et appel (normal, VOIP) est chiffré d'un Cryptophone à l'autre.<br/>
Pour que le processus fonctionne, il faut que les communications se fassent entre deux Cryptophones, sinon les données ne sont pas surprotégées (appels et messages normaux en fait).<br/>
En plus de sécuriser les informations qui transitent dans les divers réseaux, le téléphone en lui-même l'est aussi (messages, contacts et données chiffrées, l'accès au système d'exploitation rendue plus difficile avec diverses couches de sécurité à plusieurs niveaux).<br/>
Les inventeurs de ce Cryptophone sont <a href="http://rop.gonggri.jp/">Rop Gonggrijp</a> et <a href="http://blackbag.nl/">Barry Wels</a>, deux montagnes dans domaine de la sécurité informatique.<br/>
De plus, le code source est disponible, ce qui confère un degrès de confiance en plus à ce genre d'appareils.<br/>
<br/>
Bon ça reste hors de prix pour un particulier, cependant&nbsp;:<br/>
<ul>
<li>la vie privée (votre intimité) en vaut très certainement la peine</li>
<li>il y a toujours la possibilité d'en <a href="http://www.cryptofrance.fr/telephones-cryptes/location-de-telephones-cryptes/">louer</a></li>
</ul>
Vous trouverez plus d'informations à propos du système de chiffrement dans la <a href="media/2fa20186.CP500-Brochure.pdf" data-original-source="http://www.cryptophone.de/upload/files/42/original/CP500-Brochure.pdf">brochure</a>.<br/>
<br/>
<hr/>
<h3>Pour les plus pauvres d'entre nous</h3>
<br/>
Si vous être l'heureux possesseur d'un téléphone Android, il y a <a href="https://guardianproject.info">The Guardian Project</a> qui fourni des applications spécialement conçues pour l'anonymat et la sécurité de vos données. <a href="https://micahflee.com/2013/02/mobile-location-anonymity-proxying-twitter-im-and-email-through-tor-on-android/">Micah Lee</a> en parle.<br/>
Voici une liste des applications essentielles&nbsp;:<br/>
<ul>
<li><a href="https://guardianproject.info/apps/orweb">Orweb</a>, couplet à <a href="https://guardianproject.info/apps/orbot">Orbot</a> pour une navigation sur Internet en toute tranquilité</li>
<li><a href="https://guardianproject.info/apps/orbot">Orbot</a> reste indispensable, il permet de faire passer tout le trafic internet par Tor</li>
<li><a href="https://guardianproject.info/apps/gibber">Gibberbot</a>, une messagerie instantanée sécurisée</li>
<li><a href="https://ostel.me/">Ostel</a>, <a href="http://www.whispersystems.org">RedPhone</a> ou <a href="https://www.discretio.com/">Discretio</a> pour passer des appels sécurisés</li>
<li><a href="http://www.whispersystems.org">TextSecure</a> pour envoyer des SMS et MMS chiffrés</li>
</ul>
À savoir que, comme pour le Cryptophone, pour que les appels et SMS/MMS soient chiffrés, il faut que le correspondant ait la même application installée sur son téléphone.<br/>
<br/>
<hr/>
<h2>Quelques conseils</h2>
<br/>
Et pour finir... Ruez vous sur le futur <a href="https://www.mozilla.org/fr/firefox/partners/">Firefox OS</a>.<br/>
De plus, je ne saurai que vous déconseiller très fortement&nbsp;:<br/>
<ul>
<li>d'acheter ou d'utiliser le FacePhone</li>
<li>de faire confiance aux applications Google, notamment le PlayStore, passez par des markets dérivés tel que BlackMart ou F-Droid</li>
<li>d'installer les applications dont vous ne savez rien, même si elles semblent correctes, il y a tout un marché pour vous voler vos informations, alors faites attention</li>
</ul>
<hr />
Sur ce... J'espère que vous avez pris conscience du problème, mais ne tombez pas dans la paranoïa non plus ;)<br/>
<br/>
<span style="color:gray;">Si vous avez des informations à apporter ou à modifier, n'hésitez pas.</span>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130405135704
title: Faire comme dans les films
uri: Faire-comme-dans-les-films
url: https://tiger-222.fr/?d=2013/04/05/13/57/04-faire-comme-dans-les-films
content:
Souvent dans les films, c'est du grand n'importe quoi sur les écrans, alors voici quelques sites que vous pourrez mettre en plein écran pour vous la péter ;)<br/>
Et là, ce ne sont pas des salades&nbsp;!<br/>
<ul>
<li><a href="http://map.honeynet.org/">HoneyMap</a>&nbsp;: une mappemonde des pots de miel du Honeynet Project.</li>
<li><a href="http://tweetping.net/">Tweetping</a>&nbsp;: une jolie carte de Twitter.</li>
<li><a href="https://data-arts.appspot.com/globe-search/">WebGL Globe</a>&nbsp;: le globe terrestre des recherches Google. (<span style="color:teal;">MàJ du 04/03/2013</span>)</li>
<li><a href="http://globe.f-secure.com/">F-Secure Globe</a>&nbsp;: le globe terrestre des infections (virus, malware, trojans), par F-Secure. (<span style="color:teal;">MàJ du 30/05/2013</span>)</li>
</ul>
Ça l'fait&nbsp;!<br/>
<br/>
En prime, voici le super clavier&nbsp;: <a href="http://hackertyper.com/">Hacker Typer</a>. Attention, ça va très vite&nbsp;! (<span style="color:teal;">MàJ du 10/07/2013</span>)


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130405135519
title: Un peu de veille
uri: Un-peu-de-veille
url: https://tiger-222.fr/?d=2013/04/05/13/55/19-un-peu-de-veille
content:
<h2>Sites plutôt orientés C/C++ (assez technique)</h2>
<br/>
<ul>
<li><a href="http://www.altdevblogaday.com">#AltDevBlogADa</a></li>
<li><a href="http://sylvainhb.blogspot.fr/">Bilou HomeBrew's Blog</a></li>
<li><a href="http://bitsquid.blogspot.fr/">bitsquid: development blog</a></li>
<li><a href="http://byteworm.com/">Byteworm — Honk if you're compiling</a></li>
<li><a href="http://blogs.linux.ie/caolan/">Caolan McNamara (LibreOffice)</a></li>
<li><a href="http://c-skills.blogspot.fr/">C-skills</a></li>
<li><a href="http://blog.emptycrate.com/">EmptyCrate</a></li>
<li><a href="http://fastcpp.blogspot.fr/">FastC++: Coding Cpp Efficiently</a></li>
<li><a href="http://yapb-soc.blogspot.fr/">Multi-paradigm</a></li>
<li><a href="http://www.baptiste-wicht.com">@Blog("Baptiste Wicht")</a></li>
<li><a href="https://crazycpp.wordpress.com/">Crazy Eddie's Crazy C++</a></li>
<li><a href="http://create.stephan-brumme.com/">imagine. create. enjoy. de Stephan Bumme</a></li>
<li><a href="http://fabiensanglard.net/">Fabien Sanglard's website: Deep magic explained</a></li>
<li><a href="http://www.mupuf.org/">MùPùF.org</a></li>
<li><a href="https://pkisensee.wordpress.com/">LightSleeper</a></li>
<li><a href="http://herbsutter.com/feed/">Sutter’s Mill</a> (<span style="color:teal;">MàJ du 01/06/2013</span>)</li>
</ul>
<hr />
<h2>Sites orientés sécurité informatique</h2>
<br/>
<ul>
<li><a href="http://www.malekal.com/">malekal's site</a></li>
<li><a href="http://www.exploit-db.com/">Exploits Database by Offensive Security</a></li>
<li><a href="http://exploitability.blogspot.fr/">Exploitability</a></li>
<li><a href="https://journalduhack.wordpress.com/">Journal du Hack</a></li>
<li><a href="http://www.segmentationfault.fr/">Segmentation fault</a></li>
<li><a href="http://expertmiami.blogspot.fr/">Expert: Miami</a></li>
<li><a href="http://www.bortzmeyer.org/">Blog Stéphane Bortzmeyer</a></li>
<li><a href="http://blog.cryptographyengineering.com/">A Few Thoughts on Cryptographic Engineering</a></li>
<li><a href="http://blog.madpowah.org/">cloud's Blog</a></li>
<li><a href="http://vladz.devzero.fr/">vladz.devzero.fr</a></li>
<li><a href="http://binholic.blogspot.fr/">Binary world for binary people&nbsp;:)</a></li>
<li><a href="http://blog.didierstevens.com/">Didier Stevens</a></li>
<li><a href="http://www.infond.fr/">infond</a></li>
<li><a href="http://www.golubev.com/blog/">Ivan Golubev's blog - Cryptography, code optimizations, GPUs &amp; CPUs  and other</a></li>
<li><a href="https://re-xe.com/">Re-xe.Com — Reverse Engineering For Fun And Profit</a></li>
<li><a href="https://0x04.net/~mwk/reblog/">RE Blog</a></li>
<li><a href="http://blog.zx2c4.com/">Nerdling Sapple</a></li>
<li><a href="http://thanat0s.trollprod.org/">ThаnатøS Пещеру.</a> (<span style="color:teal;">MàJ du 19/03/2013</span>)</li>
</ul>
<hr />
<h2>Sites plutôt généraux mais absolument indispensables</h2>
<br/>
<ul>
<li><a href="http://sebsauvage.net/">sebsauvage.net</a></li>
<li><a href="https://news.ycombinator.com/">Hacker News</a> (<span style="color:teal;">MàJ du 24/04/2013</span>)</li>
<li><a href="http://sametmax.com/">Sam & Max: Python, Django, Git et du cul | Deux développeurs en vadrouille qui se sortent les doigts du code</a></li>
<li><a href="http://lehollandaisvolant.net">Timo - Le Hollandais Volant</a></li>
<li><a href="http://www.sur-la-toile.com/">Forum Sciences / Forum Informatique - Sur la Toile (SLT)</a></li>
<li><a href="http://www.developpez.com/">Developpez.com, le club des décideurs et professionnels en Informatique</a></li>
<li><a href="http://www.hardware.fr/">HardWare.fr - Le Guide du HardWare & de l'Optimisation PC</a></li>
<li><a href="http://reflets.info/">Reflets</a></li>
<li><a href="https://linuxfr.org/">LinuxFr.org</a></li>
<li><a href="http://arstechnica.com">Ars Technica</a> (<span style="color:teal;">MàJ du 28/05/2013</span>)</li>
</ul>
<hr />
<h2>Et enfin d'autres sites tout aussi intéressants</h2>
<br/>
<ul>
<li><a href="https://root.suumitsu.eu/">Mitsu root</a></li>
<li><a href="http://korben.info/">Korben - Site d'actualité geek et tech</a></li>
<li><a href="http://www.nikopik.com/">{niKopiK}</a></li>
<li><a href="http://www.yosko.net/">Portail Yosko.net</a></li>
<li><a href="http://geekpauvre.com/">Le Geek Pauvre</a></li>
<li><a href="https://maniacgeek.wordpress.com/">Maniac Geek</a></li>
<li><a href="http://www.memepasmal.ch/">Même pas mal!</a></li>
<li><a href="https://hacks.mozilla.org">Mozilla Hacks — the Web developer blog</a></li>
<li><a href="http://blog.idleman.fr/">IdleBlog | Le blog d'idleman: dev, graphisme, conception, analyse projet</a></li>
<li><a href="http://www.geeksaresexy.net/">Geeks are Sexy</a></li>
<li><a href="http://aryo.fr/">aryo</a></li>
<li><a href="http://zythom.blogspot.fr/">Zythom - Blog d'un informaticien expert judiciaire</a> (<span style="color:teal;">MàJ du 11/02/2013</span>)</li>
<li><a href="https://www.pcdwarf.net/">Pcdwarf.net</a> (<span style="color:teal;">MàJ du 10/02/2013</span>)</li>
<li><a href="http://sid.rstack.org/blog/index.php/">Ma petite parcelle d'Internet... Le blog de Cédric "Sid" Blancher</a></li>
<li><a href="http://news0ft.blogspot.fr/">newsoft's fun blog</a></li>
<li><a href="http://owened.co.nz/">Owened by Owen Williams</a></li>
<li><a href="http://blog.rom1v.com/">®om&#039;s blog &#8211; Un blog libre</a></li>
<li><a href="http://www.glazman.org/weblog/dotclear/">&lt;Glazblog/></a> (<span style="color:teal;">MàJ du 14/02/2013</span>)</li>
<li><a href="http://www.yankodesign.com">Yanko Design</a> (<span style="color:teal;">MàJ du 26/07/2013</span>)</li>
</ul>
<hr />
<h2>Petit final en images</h2>
<br/>
<ul>
<li><a href="http://lesjoiesducode.tumblr.com/">les_joies_du_code();</a></li>
<li><a href="http://lebescherelle.tumblr.com/">Le Bescherelle</a></li>
<li><a href="http://www.luc-damas.fr/humeurs/">Humeurs illustrées d'un enseignant-chercheur</a></li>
<li><a href="http://www.commitstrip.com/">CommitStrip - Blog relating the daily life of web agencies developers</a> (<span style="color:teal;">MàJ du 14/02/2013</span>)</li>
<li><a href="https://xkcd.com">xkcd</a></li>
</ul>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130404121212
title: Premier article
uri: Premier-article
url: https://tiger-222.fr/?d=2013/04/04/12/12/12-premier-article
content:
Premier article, surtout pour garder une trace du passé...<br/>
<br/>
<span style="font-weight: bold;">À l'heure où j'écris ces lignes...</span><br/>
Ce site est généré à l'aide de <a href="http://lehollandaisvolant.net/blogotext/fr/">BlogoText</a> 2.0.0.4.<br/>
Le thème <span style="font-style: italic;">kubik</span>, qui est de bibi, dispose de la coloration syntaxique (<a href="http://alexgorbatchev.com/SyntaxHighlighter">SyntaxHighlighter</a> 3.0.83)  et est basé sur le très bon framework <a href="http://imperavi.com/kube/">Kube CSS</a> 1.1.0.<br/>
Tu peux le <a href="http://tiger-222.fr/files/kubik-latest.zip">récupérer</a> et le modifier à ta convenance, les sources du logo sont incluses.<br/>
Le logo, parlons-en, il s'agit du symbole de <a href="https://www.gnu.org/gnu/thegnuproject.fr.html">GNU</a>, un gnou. J'ai simplement ajouté le logo de Debian GNU/Linux sur la manche du "GNU en lévitation", créé par Nevrax Design Team (<a href="https://www.gnu.org/graphics/meditate.html">sources</a>).<br/>
<br/>
<span style="font-weight: bold;">Et sinon...</span><br/>
Sur ce site, je parlerai d'un peu tout ce qui touche de près ou de loin à l'informatique avec un penchant pour la sécurité et le <span style="font-style: italic;">code</span>.<br/>
<br/>
<span style="font-weight: bold;">Et puis...</span><br/>
Sers toi parmis les différents flux RSS, ils sont là pour ça&nbsp;: articles résumés ou complets, commentaires d'un article et liens en vrac (<a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli">Shaarli</a> 0.0.41 beta).


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130404234219
title: Contact
uri: Contact
url: https://tiger-222.fr/?d=2013/04/04/23/42/19-contact
content:
<div style="text-align:center;">Vous pouvez me contacter à l'adresse suivante&nbsp;: <span style="text-decoration: underline;">contact</span> (@) <span style="text-decoration: underline;">tiger-222.fr</span></div>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130725132505
title: Utilitaire : Convertisseur d'unités
uri: Utilitaire-Convertisseur-d-unités
url: https://tiger-222.fr/?d=2013/07/25/13/25/05-utilitaire-convertisseur-dunites
content:
Je ne sais plus si c'est <a href="http://sebsauvage.net">Séb</a> qui râlait que les développeurs ne s'occupaient à écrire des outils que pour les smartphones et téléphones mobiles. Du coup, voici le premier (d'une longue liste ?) qui m'a déjà bien servi&nbsp;: un convertisseur d'unités. Le programme est multilingue, <a href="https://fr.wikipedia.org/wiki/Multiplate-forme">multiplateforme</a> et suis la <a href="https://fr.wikipedia.org/wiki/Philosophie_d%27Unix">philosophie Unix</a>.<br/>
<br/>
À l'heure où j'écris ces lignes, ce petit utilitaire sans prétention permet de convertir différentes unités d'énergie, de longueur, de masse, de surface et de temps. Libre à vous d'ajouter d'autres unités ou de faire une demande&nbsp;:)<br/>
<br/>
<div style="text-align:center;"><img src="media/8da6e8cc.unit-converter.jpg" data-original-source="http://tiger-222.fr/img/unit-converter.jpg" alt="" /></div><br/>
<hr/>
<h2>Dépendances et pré-requis</h2>
<br/>
Si vous souhaitez compiler ce petit <span style="font-style: italic;">bijou de code</span> (humour hein), il vous faudra les bibliothèques <span style="font-weight: bold;">Qt</span>. Ensuite si vous voulez modifier le code, quelques notions basiques de <span style="font-weight: bold;">C++</span> seront utiles.<br/>
<br/>
<hr/>
<h2>Téléchargement</h2>
<br/>
L'entièreté du code se trouve sur <a href="https://github.com/BoboTiG/unit-converter">GitHub</a>. Forkez, bidouillez, c'est bon pour la santé&nbsp;!<br/>
Je mettrai à disposition un exécutable pour Windows dans le dossier <span style="font-weight: bold;">packages</span>.<br/>
<br/>
<hr/>
<h2>Autres infos</h2>
<br/>
Pour me tester, j'ai voulu avoir quelques statistiques afin de pouvoir mieux évaluer mes compétences (<a href="http://www.dwheeler.com/sloccount/">sloccount</a> inside, à prendre avec des pincettes):<br/>
<ul>
<li>209 lignes de code</li>
<li>estimation du coût total&nbsp;: <a href="http://www.wolframalpha.com/input/?i=5%2C221+%24+to+%E2%82%AC">3 950 €</a></li>
<li>estimation du temps de développement&nbsp;: 1 mois et 26 jours</li>
</ul>
Plus concrêtement, j'ai passé 5 heures et 20 minutes en tout (recherches incluses), et à 35 € de l'heure, arrondi à la dizaine supérieure, ça ferait plutôt du 190 €.</li>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130723165942
title: Développement : l'estimation du temps régulièrement sous-estimée ?
uri: Développement-l-estimation-du-temps-régulièrement-sous-estimée
url:
https://tiger-222.fr/?d=2013/07/23/16/59/42-developpement-lestimation-du-temps-regulierement-sous-estimee

content:
<q>Ce qui suit est une traduction libre de l'article <a href="http://www.quora.com/Engineering-Management/Why-are-software-development-task-estimations-regularly-off-by-a-factor-of-2-3">Why are software development task estimations regularly off by a factor of 2-3?</a> de <a href="https://michaelrwolfe.wordpress.com/">Michael Wolfe</a>.</q><br/>
<h2>Pourquoi l'estimation du temps des tâches de développement est-elle régulièrement fausse d'un facteur de 2, voire 3 ?</h2>
<br/>
Partons pour une randonnée le long de la côte de San Francisco à Los Angeles pour rendre visite à nos amis de Newport Beach. Je sors ma carte et dessine notre trajet&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/8fd9d771.dev-estimation-temps-1.jpg" data-original-source="http://tiger-222.fr/img/dev-estimation-temps-1.jpg" alt="" /></div><br/>
La ligne fait environ 600 kilomètres de long ; nous pouvons marcher à 6 km/h pendant 10 heures par jour, nous y serons donc dans 10 jours. Nous appelons nos amis et prévoyons un dîner pour le dimanche suivant, en début de soirée. Nous nous ammènerons triomphalement à 18h. Ils sont impatients&nbsp;!<br/>
<br/>
Nous nous levons tôt le lendemain, excités par cette nouvelle aventure. Nous sanglons nos sacs à dos, sortons notre carte et planifions notre première journée. Nous jetons un oeil à la carte. Hmmm&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/42d6fcb6.dev-estimation-temps-2.jpg" data-original-source="http://tiger-222.fr/img/dev-estimation-temps-2.jpg" alt="" /></div><br/>
Wow, il y a 1 million de tours et de détours sur cette côte. À 6 kilomètres par jour, nous atteindrions seulement <a href="https://fr.wikipedia.org/wiki/Half_Moon_Bay">Half Moon Bay</a>. Ce voyage fait au moins 800 bornes, pas 600. Nous appelons nos amis et repoussons le dîner au mardi d'après. Mieux vaut être réaliste. Ils sont déçus, mais impatients de nous voir. Et puis 12 jours pour faire <span style="font-style: italic;">San Francisco - Los Angeles</span> ce n'est pas si mal.<br/>
<br/>
Cette contrariété réglée, nous décollons. 2 heures plus tard, nous passons seulement le zoo. Qu'est-ce que ça donne ? Nous regardons la piste&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/821a1870.dev-estimation-temps-3.jpg" data-original-source="http://tiger-222.fr/img/dev-estimation-temps-3.jpg" alt="" /></div><br/>
Quelle lenteur&nbsp;! Le sable, l'eau, les escaliers, les criques, les lions de mer agressifs&nbsp;! Nous marchons au mieux à 3 km/h, moitié moins que ce que nous voudrions. Nous pourrions marcher 20 heures par jour, ou repousser nos amis à une autre semaine. OK, ce compromis devrait être réalisable&nbsp;: nous marcherons 12 heures par jour et repoussons nos amis à la semaine d'après. Nous les appelons et retardons le dîner jusqu'au dimanche suivant. Ils sont un peu irrités mais répondent, &laquo; <span style="font-style: italic;">OK, nous vous verrons, c'est le principal</span> &raquo; .<br/>
<br/>
Après une dure journée de 12 heures de marche, nous campons à <a href="https://en.wikipedia.org/wiki/Moss_Beach,_California">Moss Beach</a>. Merde, nous n'en avons pas fini d'essayer de monter ces tentes avec ce vent. Nous ne sommes pas au lit avant minuit. Pas une grosse affaire&nbsp;: demain nous accélèrerons la cadence.<br/>
<br/>
Nous avons trop dormi et nous réveillons endoloris et épuisés à 10h. Putain&nbsp;! Plus moyen de faire nos 12 heures de marche. Nouvel objectif&nbsp;: 10h, et demain nous pourrons en faire 14. Nous rassemblons nos affaires et partons.<br/>
<br/>
Après 2 heures de longs efforts, je remarque que mon ami boite. Oh merde, des ampoules. Nous devons les soigner tout de suite... Nous sommes le genre d'équipe qui tue les problèmes dans l'oeuf, avant qu'ils ne nous ralentissent. Je cours 45 minutes et 5 kilomètres jusqu'à <a href="https://en.wikipedia.org/wiki/Pescadero,_California">Pescadero</a>, récupère quelques bandes et repars pour panser mon ami. Je suis épuisé et le soleil commence à se coucher, donc fini pour aujourd'hui. Nous allons au lit après avoir parcouru seulement 9 kilomètres. Mais nous avons des provisions fraîches. Ça ira, nous ferons la différence demain.<br/>
<br/>
Nous nous levons le matin suivant, bandons nos pieds et partons. Premier virage... Et merde&nbsp;! C'est quoi ça ?<br/>
<br/>
<div style="text-align:center;"><img src="media/c3bb8b27.dev-estimation-temps-4.jpg" data-original-source="http://tiger-222.fr/img/dev-estimation-temps-4.jpg" alt="" /></div><br/>
La maudite carte ne montrait pas ça&nbsp;! Nous avons du marcher 5 kilomètres dans les terres, autour de quelques terrains clôturés et protégés par le gouvernement fédéral, nous perdre deux fois, puis revenir sur la côte vers midi. Une grande partie de la journée perdue pour 2 kilomètres de progression. Non, nous <span style="font-weight: bold;">n'appelerons pas</span> nos amis pour repousser une fois de plus. Nous marchons jusqu'à minuit pour tenter de rattraper le retard et revenir sur le calendrier.<br/>
<br/>
Après une nuit agitée dans le brouillard, mon ami se réveille le matin avec de la fièvre accompagnée d'un mal de tête fulgurant. Je lui demande s'il peut rallier. &laquo; <span style="font-style: italic;">Qu'est-ce que tu crois, j'ai marché dans un brouillard givrant pendant 3 jours sans interruption&nbsp;!</span> &raquo; Bon, c'est mort pour aujourd'hui. Récupérons. Demain nous nous démènerons à 14 heures par jour puisque nous seront reposés... C'est  l'histoire de quelques jours de plus, largement faisable&nbsp;!<br/>
<br/>
Nous nous réveillons le lendemain matin un peu abassourdis. Je regarde la carte&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/a745b3eb.dev-estimation-temps-5.jpg" data-original-source="http://tiger-222.fr/img/dev-estimation-temps-5.jpg" alt="" /></div><br/>
Putain de merde&nbsp;! C'est déjà le cinquième jour d'un voyage de 10 et nous n'avons même pas quitté la <a href="https://fr.wikipedia.org/wiki/R%C3%A9gion_de_la_baie_de_San_Francisco">région de la baie</a>&nbsp;! C'est ridicule&nbsp;! Il faut refaire une estimation plus précise, appeler nos amis, probablement se faire crier dessus, mais obtenir un objectif plus réaliste une bonne fois pour toutes.<br/>
<q><span style="font-weight: bold;">Mon ami</span>&nbsp;: Bon, nous avons fait 64 kilomètres en 4 jours, c'est un voyage d'au moins 960 kilomètres, il nous faudrait donc 60 jours, probablement 70 pour être sûr.<br/>
<span style="font-weight: bold;">Moi</span>&nbsp;: Pas moyen... Certes, je n'ai jamais fait cette marche avant, mai je <span style="font-weight: bold;"><span style="font-style: italic;">sais</span></span> que ça ne prend pas 70 jours pour marcher de San Francisco à Los Angeles. Nos amis vont se moquer de nous si on les appelle pour leur dire que nous ne les verrons pas avant Pâques&nbsp;!</q><br/>
<q><span style="font-weight: bold;">Moi</span>&nbsp;: Si tu peux t'engager à 16 heures de marche par jour, nous pouvons faire la différence&nbsp;! Ça sera difficile, mais c'est la crise. Secoue-toi&nbsp;!<br/>
<span style="font-weight: bold;">Mon ami</span>&nbsp;: Ce n'est pas moi qui ai dit à nos amis que nous seront là pour dimanche&nbsp;! Tu es entrain de me tuer pour une erreur que tu as faite&nbsp;!</q><br/>
Un silence tendu s'installe. Personne ne passera de coup de fil aujourd'hui. J'appelerai demain lorsque mon ami aura repris ses esprits et sera prêt pour s'engager à quelque chose de raisonnable.<br/>
<br/>
Le lendemain matin, nous restons dans nos tentes jusqu'à ce qu'une tempête nous tombe dessus. La querelle de la nuit précédente passa sous silence, bien que j'ai aboyé après mon idiot d'ami quand il oublia sa bouteille au campement, et que nous ayons du perdre 30 minutes pour la récupérer. <br/>
<br/>
Je me fais une petite note mentale que nous sommes en rade de papier toilette, et qu'à la prochaine ville il faudra refaire un stock. Nous prenons un virage&nbsp;: une rivière imposante nous barre la route. Je sens que j'ai une grosse diarrhée...


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130805213531
title: Windows & python pur : capture d'écran
uri: Windows-python-pur-capture-d-écran
url: https://tiger-222.fr/?d=2013/08/05/21/35/31-windows-python-pur-capture-decran
content:
<div style="text-align:center;"><img src="media/092f536f.mss-capture-1-windows.jpg" data-original-source="http://tiger-222.fr/img/mss-capture-1-windows.jpg" alt="" /></div><br/>
Afin de décrire plus en détails le fonctionnement du module <a href="https://tiger-222.fr/?d=2013/07/01/22/34/59-module-python-multi-screen-shot">MSS</a>, je vais présenter une manière de prendre une capture d'écran (ou des écrans) en passant par les <a href="http://wikipython.flibuste.net/Ctypes">ctypes</a>.<br/>
Vite fait pour vous mettre dans le bain, ctypes est un module qui permet d'accéder aux fonctions et symboles d'une bibliothèque externe (la plupart du temps, codées en C ou C++). Du coup, on peut accéder aux fonctions du système hôte assez aisément. Cela va nous servir à imiter tout le processus effectué lorsque l'on appuie sur la touche <code class="language-markup">Imp écr Syst</code> (ou <code class="language-markup">PrtScrn</code>).<br/>
<br/>
La bonne façon de jouer avec ctypes, surtout pour ne pas avoir de surprises suivant les versions du système d'exploitation et des architectures, est de déclarer le type des arguments des fonctions ainsi que le type qu'elles retournent. Cela se fait grâce aux attributs <code class="language-markup">argtypes</code> et <code class="language-markup">restypes</code> respectivement.<br/>
<br/>
<hr />
<h2 id="processus">Processus de l'impression écran sous Windows</h2>
<br/>
Par défaut, vous vous retrouverez avec une image qui contient tous les écrans dans une seule capture. Ce fonctionnement, nous devrons le mettre en place manuellement, sinon nous nous retrouverons avec une capture de l'écran principal seulement.<br/>
<br/>
Il vous faudra appréhender quelques termes techniques dont&nbsp;:<br/>
<ul>
<li><a href="http://fr.wikipedia.org/wiki/Graphics_Device_Interface">GDI</a> ou <span style="font-weight: bold;">Graphics Device Interface</span> est une interface de périphérique graphique. Elle permet l'affichage de tout ce qui est graphique à l'écran ou sur une imprimante.</li>
<li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd183553%28v=vs.85%29.aspx">DC</a> ou <span style="font-weight: bold;">Device Context</span> est un contexte de périphérique (l'écran, l'imprimante ou un <a href="http://fr.wikipedia.org/wiki/Windows_bitmap">bitmap</a> en mémoire).</li>
</ul>
Sans plus tarder, le processus pour capturer <span style="font-weight: bold;">un seul</span> écran&nbsp;:<br/>
<ul>
<li>récupérer un ID du DC principal, càd demander l'autorisation d'utiliser le DC principal (celui qui contient toutes les fenêtres et écrans)</li>
<li>récupérer un ID vers un DC de la partie cliente, càd demander l'autorisation d'utiliser une zone mémoire pour y copier les pixels de l'écran</li>
<li>créer un bitmap compatible (zone mémoire qui contiendra les données brutes de l'image finale)</li>
<li>en très raccourci&nbsp;: copier les données brutes du DC de la partie cliente vers le bitmap en mémoire</li>
<li>finalement, transférer le bitmap en mémoire vers un fichier physique&nbsp;: notre capture d'écran</li>
</ul>
Pour prendre une capture d'un autre écran, le processus est le même, il suffira d'adapter les coordonnées et dimensions lors du transfert des pixels. Idem pour prendre une capture de tous les écrans d'un coup.<br/>
<br/>
<hr />
<h2>Les mains dans le cambouis</h2>
<br/>
<h3 id="imports">Imports</h3>
<br/>
Voici la liste des imports nécessaires ainsi que la définition des structures pour le bitmap&nbsp;:<br/>
<pre><code class="language-python">from ctypes import byref, memset, pointer, sizeof, windll<br/>
from ctypes.wintypes import (<br/>
	c_void_p as LPRECT,<br/>
	c_void_p as LPVOID,<br/>
	create_string_buffer,<br/>
	Structure,<br/>
	BOOL,<br/>
	DOUBLE,<br/>
	DWORD,<br/>
	HANDLE,<br/>
	HBITMAP,<br/>
	HDC,<br/>
	HGDIOBJ,<br/>
	HWND,<br/>
	INT,<br/>
	LPARAM,<br/>
	LONG,<br/>
	POINTER,<br/>
	RECT,<br/>
	SHORT,<br/>
	UINT,<br/>
	WINFUNCTYPE,<br/>
	WORD<br/>
)<br/>
<br/>
class BITMAPINFOHEADER(Structure):<br/>
	_fields_ = [<br/>
		('biSize', DWORD),<br/>
		('biWidth', LONG),<br/>
		('biHeight', LONG),<br/>
		('biPlanes', WORD),<br/>
		('biBitCount', WORD),<br/>
		('biCompression', DWORD),<br/>
		('biSizeImage', DWORD),<br/>
		('biXPelsPerMeter', LONG),<br/>
		('biYPelsPerMeter', LONG),<br/>
		('biClrUsed', DWORD),<br/>
		('biClrImportant', DWORD)<br/>
	]<br/>
<br/>
class BITMAPINFO(Structure):<br/>
	_fields_ = [<br/>
		('bmiHeader', BITMAPINFOHEADER),<br/>
		('bmiColors', DWORD * 3)<br/>
	]<br/>
</code></pre>
<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376%28v=vs.85%29.aspx">BITMAPINFOHEADER</a> est une structure qui défini les entêtes du fichier bitmap, <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd183375%28v=vs.85%29.aspx">BITMAPINFO</a> en est une autre qui contient une image complète (entêtes + données).<br/>
<br/>
<hr />
<h3 id="init">Initilisations</h3>
<br/>
Par soucis de lisibilité et de maintenabilité, nous allons définir nos propres variables qui seront en fait des alias de fonctions.<br/>
<pre><code class="language-python">SM_XVIRTUALSCREEN = 76  # Coordonnée gauche *<br/>
SM_YVIRTUALSCREEN = 77  # Coordonnée haute *<br/>
SM_CXVIRTUALSCREEN = 78  # Largeur en pixels *<br/>
SM_CYVIRTUALSCREEN = 79  # Hauteur en pixels *<br/>
SRCCOPY = 0xCC0020  # Code de copie pour la fonction BitBlt()<br/>
DIB_RGB_COLORS = 0<br/>
<br/>
GetSystemMetrics = windll.user32.GetSystemMetrics<br/>
EnumDisplayMonitors = windll.user32.EnumDisplayMonitors<br/>
GetWindowDC = windll.user32.GetWindowDC<br/>
CreateCompatibleDC = windll.gdi32.CreateCompatibleDC<br/>
CreateCompatibleBitmap = windll.gdi32.CreateCompatibleBitmap<br/>
SelectObject = windll.gdi32.SelectObject<br/>
BitBlt = windll.gdi32.BitBlt<br/>
GetDIBits = windll.gdi32.GetDIBits<br/>
DeleteObject = windll.gdi32.DeleteObject<br/>
</code></pre>
<span style="color:red;"><span style="font-weight: bold;">*</span></span> Il s'agit des coordonnées et dimensions de l'écran virtuel, celui qui contient tous les écrans réunis.<br/>
Pour plus d'informations sur une fonction, reportez-vous à sa documentation sur le <a href="http://msdn.microsoft.com/en-US/windows/">Windows Dev Center</a> (MSDN).<br/>
<br/>
<hr />
<h3 id="argtypes">Type d'arguments</h3>
<br/>
Bon à savoir, <code class="language-markup">argtypes</code> ne peut être qu'une liste.<br/>
<pre><code class="language-python">MONITORENUMPROC = WINFUNCTYPE(INT, DWORD, DWORD,<br/>
									POINTER(RECT), DOUBLE)<br/>
GetSystemMetrics.argtypes = [INT]<br/>
EnumDisplayMonitors.argtypes = [HDC, LPRECT, MONITORENUMPROC, LPARAM]<br/>
GetWindowDC.argtypes = [HWND]<br/>
CreateCompatibleDC.argtypes = [HDC]<br/>
CreateCompatibleBitmap.argtypes = [HDC, INT, INT]<br/>
SelectObject.argtypes = [HDC, HGDIOBJ]<br/>
BitBlt.argtypes = [HDC, INT, INT, INT, INT, HDC, INT, INT, DWORD]<br/>
DeleteObject.argtypes = [HGDIOBJ]<br/>
GetDIBits.argtypes = [HDC, HBITMAP, UINT, UINT, LPVOID,<br/>
						POINTER(BITMAPINFO), UINT]<br/>
</code></pre>
<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd145061%28v=vs.85%29.aspx">MONITORENUMPROC()</a> est une fonction de rappel (callback) pour l'énumération des écrans disponibles. Elle permet de récupérer les dimensions, coordonnées et ID de chaque écran ou de tous à la fois.<br/>
<br/>
<hr />
<h3 id="restypes">Type de fonction</h3>
<br/>
Rien de bien difficile ici, juste des types, encore et toujours.<br/>
<pre><code class="language-python">GetSystemMetrics.restypes = INT<br/>
EnumDisplayMonitors.restypes = BOOL<br/>
GetWindowDC.restypes = HDC<br/>
CreateCompatibleDC.restypes = HDC<br/>
CreateCompatibleBitmap.restypes = HBITMAP<br/>
SelectObject.restypes = HGDIOBJ<br/>
BitBlt.restypes =  BOOL<br/>
GetDIBits.restypes = INT<br/>
DeleteObject.restypes = BOOL<br/>
</code></pre>
<br/>
<hr />
<h2>C'est parti&nbsp;!</h2>
<br/>
<h3 id="enum">Informations des écrans</h3>
<br/>
Parce qu'il faut bien commencer quelque part, récupérons les dimensions et coordonnées des écrans disponibles&nbsp;:<br/>
<pre><code class="language-python">def enum_display_monitors(oneshot=False):<br/>
    # Si oneshot est à True, alors on récupère les informations de tous<br/>
    # les écrans d'un coup.<br/>
    # Retourne une liste de dictionnaires contenant les informations<br/>
    # des écrans.<br/>
<br/>
    def _callback(monitor, dc, rect, data):<br/>
        rct = rect.contents<br/>
        results.append({<br/>
            b'left' &nbsp;: int(rct.left),<br/>
            b'top'  &nbsp;: int(rct.top),<br/>
            b'width'&nbsp;: int(rct.right - rct.left),<br/>
            b'height': int(rct.bottom -rct.top)<br/>
        })<br/>
        return 1<br/>
<br/>
    results = []<br/>
    if oneshot:<br/>
        left = GetSystemMetrics(SM_XVIRTUALSCREEN)<br/>
        right = GetSystemMetrics(SM_CXVIRTUALSCREEN)<br/>
        top = GetSystemMetrics(SM_YVIRTUALSCREEN)<br/>
        bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN)<br/>
        results.append({<br/>
            b'left' &nbsp;: int(left),<br/>
            b'top'  &nbsp;: int(top),<br/>
            b'width'&nbsp;: int(right - left),<br/>
            b'height': int(bottom - top)<br/>
        })<br/>
    else:<br/>
        callback = MONITORENUMPROC(_callback)<br/>
        EnumDisplayMonitors(0, 0, callback, 0)<br/>
    return results<br/>
</code></pre>
Exemples de retour&nbsp;:<br/>
<pre><code class="language-python"># Un seul écran&nbsp;:<br/>
[{'width': 1024, 'top': 0, 'height': 768, 'left': 0}]<br/>
<br/>
# Deux écrans&nbsp;:<br/>
[<br/>
	{'width': 1366, 'top': 0, 'height': 768, 'left': 0},<br/>
	{'width': 1280, 'top': 0, 'height': 1024, 'left': 1366}<br/>
]<br/>
<br/>
# Deux écrans, oneshot=True&nbsp;:<br/>
[{'width': 2646, 'top': 0, 'height': 1024, 'left': 0}]<br/>
</code></pre>
<br/>
<hr />
<h3 id="getpixels">Récupération des pixels</h3>
<br/>
C'est ici que sont traduites les étapes du <a href="https://tiger-222.fr/#processus">§ Processus de l'impression écran sous Windows</a>.<br/>
<pre><code class="language-python">def get_pixels(monitor):<br/>
	# Récupérer les pixels d'un écran.<br/>
	<br/>
	width, height = monitor['width'], monitor['height']<br/>
	left, top = monitor['left'], monitor['top']<br/>
	<br/>
	# Récupérer un ID du DC principal<br/>
	srcdc = GetWindowDC(0)<br/>
	# Récupérer un ID vers un DC de la partie cliente<br/>
	memdc = CreateCompatibleDC(srcdc)<br/>
	# Créer un bitmap compatible<br/>
	bmp = CreateCompatibleBitmap(srcdc, width, height)<br/>
	# Sélection du bitmap nouvellement créé<br/>
	SelectObject(memdc, bmp)<br/>
	# Copie des pixels du DC principal vers le DC de la partie cliente ;<br/>
	# c'est ici qu'on spécifie les coordonnées et la taille de la capture.<br/>
	BitBlt(memdc, 0, 0, width, height, srcdc, left, top, SRCCOPY)<br/>
	# Nouvelle image BMP, remplissage des informations<br/>
	bmi = BITMAPINFO()<br/>
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER)<br/>
	bmi.bmiHeader.biWidth = width<br/>
	bmi.bmiHeader.biHeight = height<br/>
	bmi.bmiHeader.biBitCount = 24<br/>
	bmi.bmiHeader.biPlanes = 1<br/>
	# Allocation d'un buffer pour le transfert des données<br/>
	buffer_len = height * ((width * 3 + 3) & -4)<br/>
	pixels = create_string_buffer(buffer_len)<br/>
	# Récupération des données brutes (pixels) du DC de la partie cliente<br/>
	# vers l'image BMP<br/>
	bits = GetDIBits(memdc, bmp, 0, height, byref(pixels),<br/>
							pointer(bmi), DIB_RGB_COLORS)<br/>
	<br/>
	# Un peu de ménage<br/>
	DeleteObject(srcdc)<br/>
	DeleteObject(memdc)<br/>
	DeleteObject(bmp)<br/>
	<br/>
	# Vérifions que tout s'est bien passé<br/>
	if bits&nbsp;!= height or len(pixels.raw)&nbsp;!= buffer_len:<br/>
		raise ValueError('MSSWindows: GetDIBits() failed.')<br/>
<br/>
	return pixels.raw<br/>
</code></pre>
<span style="color:red;"><span style="font-weight: bold;">/!\</span></span> Dans le code, à la ligne de définition de <code class="language-markup">buffer_len</code>, il y a un <code class="language-markup">&amp;amp;</code> qui traine, il faut le remplacer par <code class="language-markup">&</code>.<br/>
<br/>
Spécialité de Microsoft oblige, le début de l'image est en bas à gauche et les pixels sont dans l'ordre BGR... Ne cherchez pas une logique là-dedans o_Ô.<br/>
<br/>
<hr />
<h3 id="main">Boucle générale</h3>
<br/>
Parce que je n'ai pas encore terminé la classe <code class="language-python">MSSImage</code> (qui permettra de se passer de module tierce pour la sauvegarde des images), nous utiliserons <a href="https://pypi.python.org/pypi/Pillow">Pillow</a> pour enregistrer l'image dans un fichier.<br/>
<pre><code class="language-python">if __name__ == '__main__':<br/>
    # Utilisation de Pillow (ou PIL) pour enregistrer l'image.<br/>
    # MSSImage est prêt mais trop long à inclure ici.<br/>
    from PIL import Image, ImageFile<br/>
<br/>
    def pil_save(filename, width, height):<br/>
        buffer_len = (width * 3 + 3) & -4<br/>
        img = Image.frombuffer('RGB', (width, height), pixels, 'raw',<br/>
            'RGB', buffer_len, 1)<br/>
        ImageFile.MAXBLOCK = width * height<br/>
        img.save(filename, quality=95, optimize=True, progressive=True)<br/>
        print('Fichier {0} créé.'.format(filename))<br/>
<br/>
    # Une capture par écran<br/>
    i = 1<br/>
    for monitor in enum_display_monitors():<br/>
        pixels = get_pixels(monitor)<br/>
        filename = 'mss-capture-{0}.jpg'.format(i)<br/>
        pil_save(filename, monitor['width'], monitor['height'])<br/>
        i += 1<br/>
<br/>
    # Capture complète<br/>
    monitor = enum_display_monitors(oneshot=True)[0]<br/>
    pixels = get_pixels(monitor)<br/>
    filename = 'mss-capture-complet.jpg'<br/>
    pil_save(filename, monitor['width'], monitor['height'])<br/>
</code></pre>
<span style="color:red;"><span style="font-weight: bold;">/!\</span></span> Dans le code, à la ligne de définition de <code class="language-markup">buffer_len</code>, il y a un <code class="language-markup">&amp;amp;</code> qui traine, il faut le remplacer par <code class="language-markup">&</code>.<br/>
<br/>
Dans la fonction <code class="language-python">Image.frombuffer()</code>, c'est le dernier argument qui permet de spécifier que le début de l'image est en bas à gauche (<span style="font-weight: bold;">-1</span>).<br/>
<br/>
Voici le <a href="http://tiger-222.fr/files/mss-windows.py">script complet</a>, et la <a href="media/4df32adf.mss-capture-2-windows.jpg" data-original-source="http://tiger-222.fr/img/mss-capture-2-windows.jpg">capture d'écran</a> c'est cadeau&nbsp;:)<br/>
<br/>
<hr />
<h2 id="bonus">Bonus</h2>
<br/>
Juste pour le fun, j'ai mis en place une <a href="https://tiger-222.fr/tout/python-mss/galerie/">galerie d'images</a> sans prétention afin d'exposer les captures d'écran <span style="font-style: italic;">oneshot</span> que vous me ferez parvenir ☺<br/>
<br/>
<hr />
<h2 id="sources">Sources diverses</h2>
<br/>
<ul>
<li><a href="http://stackoverflow.com/questions/17394685/screenshot-ctypes-windll-createdcfromhandle">Screenshot (ctypes.windll CreateDCFromHandle) - Stack Overflow</a></li>
<li><a href="http://texel3d.free.fr/win32/base3.htm">Texel: Les bases de la programmation Windows (Api Win32)</a></li>
<li>Photographies venant de Wallbase.cc&nbsp;: <a href="http://wallbase.cc/wallpaper/2286563">le tigre</a> et <a href="http://wallbase.cc/wallpaper/1106896">la jolie Anna Demi</a> (<a href="media/1a99df9a.Anna_Demi.jpg" data-original-source="https://tiger-222.fr/img/Anna_Demi.jpg">copie locale</a>)</li>
</ul>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130808163829
title: Windows 7 Starter & fond d'écran
uri: Windows-7-Starter-fond-d-écran
url: https://tiger-222.fr/?d=2013/08/08/16/38/29-windows-7-starter-fond-decran
content:
<h2>Qui a la plus grosse</h2>
<br/>
Dans la série &laquo; <span style="font-style: italic;">Je suis Microsoft le géant, je pense pouvoir faire ce que je veux, donc je fais n'importe quoi&nbsp;!</span> &raquo;, j'ai, à ma grande surprise, constaté qu'il n'est pas possible de changer de fond d'écran sur les versions de Windows 7 <span style="font-weight: bold;">Starter</span> et <span style="font-weight: bold;">Starter N</span>...<br/>
Pourquoi cette tragique disparition ? Nous ne le saurons peut-être jamais. Cependant, grâce aux efforts de bidouilleurs, nos sauveurs, il existe quelques utilitaires qui corrigent le tir. <br/>
<br/>
<hr />
<h2>Solution</h2>
<br/>
Je me suis attardé sur <a href="http://renaudgerson.fr/StarterBackgroundChanger/">Starter Change Background</a>, écrit par un français, et qui fait parfaitement l'affaire&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/4a379ec1.starter-change-background.jpg" data-original-source="http://tiger-222.fr/img/starter-change-background.jpg" alt="" /></div><br/>
L'<a href="http://renaudgerson.fr/StarterBackgroundChanger/comment-linstaller/">installation est simplissime</a>, son <a href="http://renaudgerson.fr/StarterBackgroundChanger/comment-lutiliser-2/">fonctionnement</a> l'est tout aussi. Pour accéder au gestionnaire d'arrière plan&nbsp;:<br/>
<ul>
<li><span style="font-weight: bold;">clic droit</span> sur le <code class="language-markup">Bureau</code> et choisir <code class="language-markup">Personnaliser</code> ;</li>
<li>ou faire un <span style="font-weight: bold;">clic droit</span> sur une image et sélectionner <code class="language-markup">Choisir comme fond d’écran</code></li>
</ul>
<hr />
<h3>L'ordinal 459...</h3>
<br/>
Si, lorsque vous lancez le programme, vous avez ce joli message récurrent pas vraiment compréhensible&nbsp;:<br/>
<q>L'ordinal 459 est introuvable dans la bibliothèque de liens dynamiques urlmon.dll.<br/>
</q><br/>
C'est qu'<a href="media/7e7ac150.003b.jpg" data-original-source="http://www.museum-neuchatel.ch/new/images/dynamic/pages/60/003b.jpg">il y a anguille sous roche</a>&nbsp;! Cela m'est arrivé parce que j'avais désinstallé ce maudit <a href="http://www.commitstrip.com/fr/2012/10/31/mais-quand-vont-ils-labandonner/">Internet Explorer</a>. J'ai du le <a href="https://answers.microsoft.com/en-us/windows/forum/windows_vista-performance/the-ordinal-459-could-not-be-located-in-the/d93d1cdf-763b-4403-bcc8-ca06d16f4f4a?page=2#LastReply">réinstaller</a>, puis faire les mise à jour à l'aide de <a href="http://www.commitstrip.com/fr/2013/06/27/scumbag-windows/">Windows Update</a>. Je n'en suis pas peu fier...


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130807183949
title: GNU/Linux & python pur : capture d'écran
uri: GNU-Linux-python-pur-capture-d-écran
url: https://tiger-222.fr/?d=2013/08/07/18/39/49-gnulinux-python-pur-capture-decran
content:
<span style="font-weight: bold;"><span style="color:teal;">MàJ du 2013-10-21</span></span>&nbsp;: support de python 3<br/>
<span style="font-weight: bold;"><span style="color:teal;">MàJ du 2013-08-17</span></span>&nbsp;: correction de la segfault, voir <a href="https://tiger-222.fr/#erreur">§ Erreurs</a> ; meilleur gestion du serveur X<br/>
<span style="font-weight: bold;"><span style="color:teal;">MàJ du 2013-08-16</span></span>&nbsp;: correction de la détermination des coordonnées et dimensions (merci à <a href="https://www.ecirtam.net/">Oros</a>)<br/>
<hr/>
<div style="text-align:center;"><img src="media/6d33efeb.mss-capture-1-linux.jpg" data-original-source="http://tiger-222.fr/img/mss-capture-1-linux.jpg" alt="" /></div><br/>
Afin de décrire plus en détails le fonctionnement du module <a href="https://tiger-222.fr/?d=2013/07/01/22/34/59-module-python-multi-screen-shot">MSS</a>, je vais présenter une manière de prendre une capture d'écran (ou des écrans) en passant par le module <a href="http://wikipython.flibuste.net/Ctypes">ctypes</a>. Il existe déjà un article qui <a href="https://tiger-222.fr/index.php?d=2013/08/05/21/35/31-windows-python-pur-capture-decran">détaille le processus pour Windows</a>.<br/>
<br/>
La bonne façon de jouer avec ctypes, surtout pour ne pas avoir de surprises suivant les versions du système d'exploitation et des architectures, est de déclarer le type des arguments des fonctions ainsi que le type qu'elles retournent. Cela se fait grâce aux attributs <code class="language-markup">argtypes</code> et <code class="language-markup">restypes</code> respectivement.<br/>
<br/>
GNU/Linux, ce n'est pas un système unique, donc il va falloir jouer sur plusieurs tableaux, charger les bonnes bibliothèques, etc. Ici, nous nous préoccuperons seulement de <a href="https://fr.wikipedia.org/wiki/Xlib">Xlib</a>, tout simplement parce qu'il est quasiment omniprésent, et ensuite parce que c'est ce qui gère mon système (Debian GNU/Linux jessie 64 bits + Mate).  J'ai ajouté une <a href="https://tiger-222.fr/#remarques">liste des choses à améliorer</a>, j'y travaille activement.<br/>
<br/>
<hr />
<h2 id="processus">Processus de l'impression écran sous GNU/Linux</h2>
<br/>
Par défaut, vous vous retrouverez avec une image qui contient tous les écrans dans une seule capture. Ce fonctionnement est aussi celui par défaut lorsqu'on utilise la bibliothèque Xlib. Ce qu'il faudra mettre en place manuellement, c'est une capture par écran.<br/>
<br/>
Voici le processus pour capturer <span style="font-weight: bold;">une zone</span> du serveur X &nbsp;:<br/>
<ul>
<li>connexion au serveur</li>
<li>récupérer un ID vers la fenêtre racine</li>
<li>récupérer une image de la zone désirée</li>
<li>copier les pixels de le l'image</li>
<li>enregistrer les pixels dans une image physique</li>
</ul>
<hr />
<h2>Les mains dans le cambouis</h2>
<br/>
<h3 id="imports">Imports</h3>
<br/>
Voici la liste des imports nécessaires&nbsp;:<br/>
<pre><code class="language-python"># Pour la capture d'un seul écran, il faut lire un XML de l'utilisateur<br/>
from os.path import expanduser, isfile<br/>
import xml.etree.ElementTree as ET<br/>
<br/>
# Pour la variable d'environnement $DISPLAY<br/>
from os import environ<br/>
<br/>
from struct import pack<br/>
from ctypes.util import find_library<br/>
from ctypes import byref, cast, cdll<br/>
from ctypes import (<br/>
	c_char_p, c_int, c_int32, c_uint, c_uint32,<br/>
	c_ulong, c_void_p, POINTER, Structure<br/>
)<br/>
<br/>
class Display(Structure):<br/>
	pass<br/>
<br/>
class XWindowAttributes(Structure):<br/>
	_fields_ = [<br/>
		("x",                     c_int32),<br/>
		("y",                     c_int32),<br/>
		("width",                 c_int32),<br/>
		("height",                c_int32),<br/>
		("border_width",          c_int32),<br/>
		("depth",                 c_int32),<br/>
		("visual",                c_ulong),<br/>
		("root",                  c_ulong),<br/>
		("class",                 c_int32),<br/>
		("bit_gravity",           c_int32),<br/>
		("win_gravity",           c_int32),<br/>
		("backing_store",         c_int32),<br/>
		("backing_planes",        c_ulong),<br/>
		("backing_pixel",         c_ulong),<br/>
		("save_under",            c_int32),<br/>
		("colourmap",             c_ulong),<br/>
		("mapinstalled",          c_uint32),<br/>
		("map_state",             c_uint32),<br/>
		("all_event_masks",       c_ulong),<br/>
		("your_event_mask",       c_ulong),<br/>
		("do_not_propagate_mask", c_ulong),<br/>
		("override_redirect",     c_int32),<br/>
		("screen",                c_ulong)<br/>
	]<br/>
<br/>
class XImage(Structure):<br/>
	_fields_ = [<br/>
		('width'            , c_int),<br/>
		('height'           , c_int),<br/>
		('xoffset'          , c_int),<br/>
		('format'           , c_int),<br/>
		('data'             , c_char_p),<br/>
		('byte_order'       , c_int),<br/>
		('bitmap_unit'      , c_int),<br/>
		('bitmap_bit_order' , c_int),<br/>
		('bitmap_pad'       , c_int),<br/>
		('depth'            , c_int),<br/>
		('bytes_per_line'   , c_int),<br/>
		('bits_per_pixel'   , c_int),<br/>
		('red_mask'         , c_ulong),<br/>
		('green_mask'       , c_ulong),<br/>
		('blue_mask'        , c_ulong)<br/>
	]<br/>
<br/>
def b(x):<br/>
	return pack(b'<B', x)<br/>
</code></pre>
<br/>
<hr />
<h3 id="init">Initilisations</h3>
<br/>
Par soucis de lisibilité et de maintenabilité, nous allons définir nos propres variables qui seront en fait des alias de fonctions.<br/>
<pre><code class="language-python"># Chargement de la bibliothèque Xlib<br/>
x11 = find_library('X11')<br/>
if x11 is None:<br/>
	raise OSError('MSSLinux: no X11 library found.')<br/>
else:<br/>
	xlib = cdll.LoadLibrary(x11)<br/>
<br/>
XOpenDisplay = xlib.XOpenDisplay<br/>
XDefaultScreen = xlib.XDefaultScreen<br/>
XDefaultRootWindow = xlib.XDefaultRootWindow<br/>
XGetWindowAttributes = xlib.XGetWindowAttributes<br/>
XAllPlanes = xlib.XAllPlanes<br/>
XGetImage = xlib.XGetImage<br/>
XGetPixel = xlib.XGetPixel<br/>
XCreateImage = xlib.XCreateImage<br/>
XFree = xlib.XFree<br/>
</code></pre>
Pour plus d'informations sur une fonction, reportez-vous à sa <a href="http://tronche.com/gui/x/xlib/">documentation en ligne</a>.<br/>
<br/>
<hr />
<h3 id="argtypes">Type d'arguments</h3>
<br/>
Bon à savoir, <code class="language-markup">argtypes</code> ne peut être qu'une liste.<br/>
<pre><code class="language-python">XOpenDisplay.argtypes = [c_char_p]<br/>
XDefaultScreen.argtypes = [POINTER(Display)]<br/>
XDefaultRootWindow.argtypes = [POINTER(Display)]<br/>
XGetWindowAttributes.argtypes = [POINTER(Display),<br/>
	POINTER(XWindowAttributes), POINTER(XWindowAttributes)]<br/>
XAllPlanes.argtypes = []<br/>
XGetImage.argtypes = [POINTER(Display), POINTER(Display),<br/>
	c_int, c_int, c_uint, c_uint, c_ulong, c_int]<br/>
XGetPixel.argtypes = [POINTER(XImage), c_int, c_int]<br/>
XCreateImage.argtypes = [POINTER(Display), POINTER(Display),<br/>
	c_int, c_int, c_uint, c_uint, c_ulong, c_int]<br/>
XFree.argtypes = [POINTER(XImage)]<br/>
</code></pre>
<br/>
<hr />
<h3 id="restypes">Type de fonction</h3>
<br/>
Rien de bien difficile ici, juste des types, encore et toujours.<br/>
<pre><code class="language-python">XOpenDisplay.restype = POINTER(Display)<br/>
XDefaultScreen.restype = c_int<br/>
XDefaultRootWindow.restype = POINTER(XWindowAttributes)<br/>
XGetWindowAttributes.restype = c_int<br/>
XAllPlanes.restype = c_ulong<br/>
XGetImage.restype = POINTER(XImage)<br/>
XGetPixel.restype = c_ulong<br/>
XCreateImage.restype = POINTER(XImage)<br/>
XFree.restype = c_void_p<br/>
</code></pre>
<br/>
<hr />
<h2>C'est parti&nbsp;!</h2>
<br/>
<h3 id="enum">Informations des écrans</h3>
<br/>
Parce qu'il faut bien commencer quelque part, récupérons les dimensions et coordonnées des écrans disponibles&nbsp;:<br/>
<pre><code class="language-python">def enum_display_monitors(oneshot=False):<br/>
    # Si oneshot est à True, alors on récupère les informations de tous<br/>
    # les écrans d'un coup.<br/>
    # Retourne une liste de dictionnaires contenant les informations<br/>
    # des écran.<br/>
<br/>
    results = []<br/>
    if oneshot:<br/>
        gwa = XWindowAttributes()<br/>
        XGetWindowAttributes(display, root_win, byref(gwa))<br/>
        infos = {<br/>
            b'left' &nbsp;: int(gwa.x),<br/>
            b'top'  &nbsp;: int(gwa.y),<br/>
            b'width'&nbsp;: int(gwa.width),<br/>
            b'height': int(gwa.height)<br/>
        }<br/>
        results.append(infos)<br/>
    else:<br/>
        # C'est un chouilla plus compliqué, nous devons trouver les infos<br/>
        # dans le fichier ~/.config/monitors.xml, si présent. Je n'ai pas<br/>
        # encore trouvé un moyen de le faire à l'aide de Xlib.<br/>
        monitors = expanduser('~/.config/monitors.xml')<br/>
        if not isfile(monitors):<br/>
            print('MSSLinux: _enum_display_monitors() failed (no monitors.xml).')<br/>
            return enum_display_monitors(oneshot=True)<br/>
        conf = []<br/>
        tree = ET.parse(monitors)<br/>
        root = tree.getroot()<br/>
        config = root.findall('configuration')[-1]<br/>
        for output in config.findall('output'):<br/>
            name = output.get('name')<br/>
            if name&nbsp;!= 'default':<br/>
                x = output.find('x')<br/>
                y = output.find('y')<br/>
                width = output.find('width')<br/>
                height = output.find('height')<br/>
                rotation = output.find('rotation')<br/>
                if None not in [x, y, width, height] and name not in conf:<br/>
                    conf.append(name)<br/>
                    if rotation.text == 'left' or rotation.text == 'right':<br/>
                        width, height = height, width<br/>
                    results.append({<br/>
                        b'left'   &nbsp;: int(x.text),<br/>
                        b'top'    &nbsp;: int(y.text),<br/>
                        b'width'  &nbsp;: int(width.text),<br/>
                        b'height' &nbsp;: int(height.text),<br/>
                        b'rotation': rotation.text<br/>
                    })<br/>
    return results<br/>
</code></pre>
<br/>
Exemple de fichier <span style="font-style: italic;">~/.config/monitors.xml</span>&nbsp;:<br/>
<pre><code class="language-markup">&lt;configuration>
	&lt;clone>no&lt;/clone><br/>
	&lt;output name="VGA-0"><br/>
		&lt;vendor>AIC&lt;/vendor><br/>
		&lt;product>0x4191&lt;/product><br/>
		&lt;serial>0x00000346&lt;/serial><br/>
		&lt;width>1280&lt;/width><br/>
		&lt;height>1024&lt;/height><br/>
		&lt;rate>60&lt;/rate><br/>
		&lt;x>0&lt;/x><br/>
		&lt;y>0&lt;/y><br/>
		&lt;rotation>normal&lt;/rotation><br/>
		&lt;reflect_x>no&lt;/reflect_x><br/>
		&lt;reflect_y>no&lt;/reflect_y><br/>
		&lt;primary>yes&lt;/primary><br/>
	&lt;/output><br/>
	&lt;output name="DVI-I-0"><br/>
	&lt;/output><br/>
	&lt;output name="HDMI-0"><br/>
	&lt;/output><br/>
	&lt;output name="DVI-I-1"><br/>
		&lt;vendor>AOC&lt;/vendor><br/>
		&lt;product>0x2260&lt;/product><br/>
		&lt;serial>0x0000051a&lt;/serial><br/>
		&lt;width>1920&lt;/width><br/>
		&lt;height>1080&lt;/height><br/>
		&lt;rate>60&lt;/rate><br/>
		&lt;x>1280&lt;/x><br/>
		&lt;y>0&lt;/y><br/>
		&lt;rotation>left&lt;/rotation><br/>
		&lt;reflect_x>no&lt;/reflect_x><br/>
		&lt;reflect_y>no&lt;/reflect_y><br/>
		&lt;primary>no&lt;/primary><br/>
	&lt;/output><br/>
&lt;/configuration><br/>
</code></pre>
<br/>
Exemples de retour&nbsp;:<br/>
<pre><code class="language-python"># Un seul écran&nbsp;:<br/>
[{'width': 1280, 'top': 0, 'height': 1024, 'left': 0}]<br/>
<br/>
# Deux écrans&nbsp;:<br/>
[<br/>
	{'width': 1280, 'top': 0, 'rotation': 'normal', 'height': 1024, 'left': 0},<br/>
	{'width': 1920, 'top': 0, 'rotation': 'left', 'height': 1080, 'left': 1280}<br/>
]<br/>
<br/>
# Deux écrans, oneshot=True&nbsp;:<br/>
[{'width': 2360, 'top': 0, 'height': 1920, 'left': 0}]<br/>
</code></pre>
<br/>
<hr />
<h3 id="getpixels">Récupération des pixels</h3>
<br/>
C'est ici que sont traduites les étapes du <a href="https://tiger-222.fr/#processus">§ Processus de l'impression écran sous GNU/Linux</a>.<br/>
<pre><code class="language-python">def get_pixels(monitor):<br/>
	# Récupérer les pixels d'un écran.<br/>
	<br/>
	width, height = monitor[b'width'], monitor[b'height']<br/>
	left, top = monitor[b'left'], monitor[b'top']<br/>
	ZPixmap = 2<br/>
<br/>
	allplanes = XAllPlanes()<br/>
	ZPixmap = 2<br/>
<br/>
	# Fix pour XGetImage: expected LP_Display instance instead of LP_XWindowAttributes<br/>
	root = cast(root_win, POINTER(Display))<br/>
<br/>
	image = XGetImage(display, root, left, top, width, height, allplanes, ZPixmap)<br/>
	if image is None:<br/>
		raise ValueError('MSSLinux: XGetImage() failed.')<br/>
<br/>
	pixels = [b'0'] * (3 * width * height)<br/>
	for x in range(width):<br/>
		for y in range(height):<br/>
			pixel = XGetPixel(image, x, y)<br/>
			blue = pixel & 255<br/>
			green = (pixel & 65280) >> 8<br/>
			red = (pixel & 16711680) >> 16<br/>
			offset = (x + width * y) * 3<br/>
			pixels[offset:offset+3] = b(red), b(green), b(blue)<br/>
	XFree(image)<br/>
	return b''.join(pixels)<br/>
</code></pre>
<span style="color:red;"><span style="font-weight: bold;">/!\</span></span> Dans le code, aux lignes de calcul des pixels <code class="language-markup">r, g, b</code>, il y a un <code class="language-markup">&amp;amp;</code> qui traine, il faut le remplacer par <code class="language-markup">&</code>.<br/>
<br/>
<hr />
<h3 id="main">Boucle générale</h3>
<br/>
Parce qu'il serait trop long d'inclure la classe <code class="language-python">MSSImage</code> (qui permettra de se passer de module tierce pour la sauvegarde des images), nous utiliserons <a href="https://pypi.python.org/pypi/Pillow">Pillow</a> pour enregistrer l'image dans un fichier.<br/>
<pre><code class="language-python">if __name__ == '__main__':<br/>
    # Utilisation de Pillow (ou PIL) pour enregistrer l'image.<br/>
    # MSSImage est prêt mais trop long à inclure ici.<br/>
    from PIL import Image, ImageFile<br/>
<br/>
    def pil_save(filename, width, height):<br/>
        buffer_len = (width * 3 + 3) & -4<br/>
        img = Image.frombuffer('RGB', (width, height), pixels, 'raw',<br/>
            'RGB', buffer_len, 1)<br/>
        ImageFile.MAXBLOCK = width * height<br/>
        img.save(filename, quality=95, optimize=True, progressive=True)<br/>
        print('Fichier {0} créé.'.format(filename))<br/>
<br/>
    # Une capture par écran<br/>
    i = 1<br/>
    for monitor in enum_display_monitors():<br/>
        pixels = get_pixels(monitor)<br/>
        filename = 'mss-capture-{0}.jpg'.format(i)<br/>
        pil_save(filename, monitor['width'], monitor['height'])<br/>
        i += 1<br/>
<br/>
    # Capture complète<br/>
    monitor = enum_display_monitors(oneshot=True)[0]<br/>
    pixels = get_pixels(monitor)<br/>
    filename = 'mss-capture-complet.jpg'<br/>
    pil_save(filename, monitor['width'], monitor['height'])<br/>
</code></pre>
<span style="color:red;"><span style="font-weight: bold;">/!\</span></span> Dans le code, à la ligne de définition de <code class="language-markup">buffer_len</code>, il y a un <code class="language-markup">&amp;amp;</code> qui traine, il faut le remplacer par <code class="language-markup">&</code>.<br/>
<br/>
Voici le <a href="http://tiger-222.fr/files/mss-linux.py">script complet</a>, et la <a href="media/e1b53eb0.mss-capture-2-linux.jpg" data-original-source="http://tiger-222.fr/img/mss-capture-2-linux.jpg">capture d'écran</a> c'est cadeau&nbsp;:)<br/>
<br/>
<hr />
<h2 id="erreur">Erreurs</h2>
<br/>
Si vous prenez une machine par SSH, pensez à activé le transfert de X11, grâce à l'option <code class="language-python">-X</code>. Sinon, vous tomberez sur une faute de segmentation.<br/>
<br/>
<hr />
<h2 id="bonus">Bonus</h2>
<br/>
Juste pour le fun, j'ai mis en place une <a href="https://tiger-222.fr/tout/python-mss/galerie/">galerie d'images</a> sans prétention afin d'exposer les captures d'écran <span style="font-style: italic;">oneshot</span> que vous me ferez parvenir ☺<br/>
<br/>
<hr />
<h2 id="remarques">Remarques</h2>
<br/>
Le code présenté ne peut, dans l'immédiat, être certain de fonctionner suivant votre configuration. Je sais, c'est moche de présenter un code bancal, mais c'est un 1<sup>er</sup> jet et ça devrait être correct pour la plupart d'entre vous. Pour ceux et celles qui sont motivés, voici quelques points à améliorer (le code est simple, passez par <a href="https://github.com/BoboTiG/python-mss">GitHub</a>)&nbsp;:<br/>
<br/>
<ul>
<li>c'est lent, très lent, trop lent à mon goût&nbsp;: il faudrait pouvoir se passer de la boucle du <code class="language-python">XGetPixel()</code>, voir si on peut copier/coller directement une zone de l'écran vers un fichier physique (JPEG/PNG)</li>
<li><span style="text-decoration: line-through;">capturer le bureau virtuel actif</span> OK</li>
<li><span style="text-decoration: line-through;">comprendre pourquoi il y a une faute de segmentation (aléatoire ?) sur les systèmes 32 bits</span> OK, voir <a href="https://tiger-222.fr/#erreur">§ Erreurs</a></li>
<li><span style="text-decoration: line-through;">supporter python 3</span> OK</li>
<li>supporter <a href="https://fr.wikipedia.org/wiki/XCB">XCB</a></li>
<li>qu'en est-il de <a href="https://fr.wikipedia.org/wiki/Wayland">Wayland</a> ?</li>
<li>autres ?</li>
</ul>
<hr />
<h2 id=sources">Sources diverses</h2>
<br/>
<ul>
<li><a href="http://tronche.com/gui/x/xlib/">Xlib Programming Manual</a></li>
<li><a href="http://python-pyknic.googlecode.com/svn-history/r384/trunk/experimental/windowmanipulator/xlib/x11/xlib.py">Code source de Pyknic</a></li>
<li><a href="http://www.gelato.unsw.edu.au/IA64wiki/XGetWindowProperty">Minimal XGetWindowProperty Example</a></li>
<li>Photographies venant de Wallbase.cc&nbsp;: <a href="http://wallbase.cc/wallpaper/2286563">le tigre</a> et <a href="http://wallbase.cc/wallpaper/1106896">la jolie Anna Demi</a> (<a href="media/1a99df9a.Anna_Demi.jpg" data-original-source="https://tiger-222.fr/img/Anna_Demi.jpg">copie locale</a>)</li>
</ul>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130825190012
title: Mac & python natif : capture d'écran
uri: Mac-python-natif-capture-d-écran
url: https://tiger-222.fr/?d=2013/08/25/19/00/12-mac-python-natif-capture-decran
content:
<div style="text-align:center;"><img src="media/6363a1ab.mss-capture-1-mac.jpg" data-original-source="http://tiger-222.fr/img/mss-capture-1-mac.jpg" alt="" /></div><br/>
Afin de décrire plus en détails le fonctionnement du module <a href="https://tiger-222.fr/?d=2013/07/01/22/34/59-module-python-multi-screen-shot">MSS</a>, je vais présenter une manière de prendre une capture d'écran (ou des écrans) en utilisant seulement du python natif, à l'aide du module <a href="https://fr.wikipedia.org/wiki/Quartz_%28informatique%29">Quartz</a>. Je ferai certainement des tests avec le module <a href="http://wikipython.flibuste.net/Ctypes">ctypes</a> plus tard, mais ça ne sera pas mieux que ce qui est présenté dans cet article (plus long et fastidieux, ceci dit c'est intéressant pour le côté technique). Il existe déjà des articles qui détaillent le processus pour <a href="https://tiger-222.fr/index.php?d=2013/08/05/21/35/31-windows-python-pur-capture-decran">Windows</a> et <a href="https://tiger-222.fr/index.php?d=2013/08/07/18/39/49-gnulinux-python-pur-capture-decran">GNU/Linux</a>.<br/>
<br/>
Les tests ont été effectués sous <a href="http://www.aprogia.com/archives/495">Mac OS X Lion sur Virtualbox</a> et Mac OS X Mountain Lion (merci à Eownis). D'après la documentation officielle, le script présenté ici devrait être fonctionnel sur quasiment toutes les déclinaisons de Mac OS X, voire même iOS (je m'avance peut-être, n'étant pas un fervent adepte d'Apple, je manque cruellement de matériel).<br/>
<br/>
<hr />
<h2 id="imports">Imports</h2>
<br/>
Voici la liste des imports nécessaires&nbsp;:<br/>
<pre><code class="language-python">from Quartz import *<br/>
<br/>
# Nécessaire pour l'enregistrement de la capture dans un fichier.<br/>
# Ici, on utilise le PNG, mais d'autres formats existent [UTType]<br/>
from LaunchServices import kUTTypePNG<br/>
</code></pre>
<code>[UTType]</code> Dans le document <a href="https://developer.apple.com/library/ios/documentation/MobileCoreServices/Reference/UTTypeRef/Reference/reference.html">UTType Reference</a>, on peut trouver, entre autres, le type JPEG (<code class="language-python">kUTTypeJPEG</code>) ou encore GIF (<code class="language-python">kUTTypeGIF</code>).<br/>
<br/>
<hr />
<h3 id="enum">Informations des écrans</h3>
<br/>
Parce qu'il faut bien commencer quelque part, récupérons les dimensions et coordonnées des écrans disponibles. Le nom des fonctions est assez explicite&nbsp;:<br/>
<pre><code class="language-python">def enum_display_monitors(oneshot=False):<br/>
    # Si oneshot est à True, alors on récupère les informations de tous<br/>
    # les écrans d'un coup.<br/>
    # Retourne une liste de dictionnaires contenant les informations<br/>
    # des écran.<br/>
<br/>
    results = []<br/>
    if oneshot:<br/>
        rect = CGRectInfinite<br/>
        results.append({<br/>
            b'left'   &nbsp;: int(rect.origin.x),<br/>
            b'top'    &nbsp;: int(rect.origin.y),<br/>
            b'width'  &nbsp;: int(rect.size.width),<br/>
            b'height' &nbsp;: int(rect.size.height)<br/>
        })<br/>
    else:<br/>
        max_displays = 32  # Peut-être augmenté, si besoin...<br/>
        rotations = {0.0: 'normal', 90.0: 'right', -90.0: 'left'}<br/>
        res, ids, count = CGGetActiveDisplayList(max_displays, None, None)<br/>
        for display in ids:<br/>
            rect = CGRectStandardize(CGDisplayBounds(display))<br/>
            left, top = rect.origin.x, rect.origin.y<br/>
            width, height = rect.size.width, rect.size.height<br/>
            <br/>
            # La fonction suivante retourne un double pour exprimer la<br/>
            # rotation de l'écran&nbsp;: 0.0, 90.0, -90.0, ... On le traduit<br/>
            # par normal, left ou right, plus compréhensible.<br/>
            rot = CGDisplayRotation(display)<br/>
            rotation = rotations[rot]<br/>
            if rotation in ['left', 'right']:<br/>
                width, height = height, width<br/>
            results.append({<br/>
                b'left'   &nbsp;: int(left),<br/>
                b'top'    &nbsp;: int(top),<br/>
                b'width'  &nbsp;: int(width),<br/>
                b'height' &nbsp;: int(height),<br/>
                b'rotation': rotation<br/>
            })<br/>
    return results<br/>
</code></pre>
Si <code class="language-python">onshot=True</code>, nous utilisons <code class="language-python">CGRectInfinite</code> qui renvoie des données assez... monstrueuses&nbsp;! Je vous laisse tester pour <a href="media/d19855de.mss-capture-terminal-mac.png" data-original-source="http://tiger-222.fr/img/mss-capture-terminal-mac.png">voir ce que ça donne</a>, ça n'est pas utilisable en l'état. Mais une option dans la fonction suivante permettra de rectifier le tir.<br/>
<br/>
Exemples de retour&nbsp;:<br/>
<pre><code class="language-python"># Un seul écran&nbsp;:<br/>
[{'width': 1280, 'top': 0, 'height': 800, 'left': 0}]<br/>
<br/>
# Deux écrans&nbsp;:<br/>
[<br/>
	{'width': 1280, 'top': 0, 'rotation': 'normal', 'height': 800, 'left': 0},<br/>
	{'width': 1360, 'top': 32, 'rotation': 'normal', 'height': 768, 'left': -1360}<br/>
]<br/>
<br/>
# Deux écrans, oneshot=True&nbsp;:<br/>
[{'width': 179769..., 'top': -89884..., 'height': 179769..., 'left': -89884...}]<br/>
</code></pre>
<br/>
<hr />
<h3 id="getpixels">Récupération des pixels et enregistrement</h3>
<br/>
Le module Quartz est vraiment cool à utiliser, voyez comme il est facile de récupérer les données de l'écran et les enregistrer dans un fichier PNG&nbsp;:<br/>
<pre><code class="language-python">def get_pixels_and_save(monitor, filename):<br/>
    # Récupérer les pixels d'un écran, puis enregistrement.<br/>
<br/>
    width, height = monitor[b'width'], monitor[b'height']<br/>
    left, top = monitor[b'left'], monitor[b'top']<br/>
    dpi = 72<br/>
<br/>
    # Récupération des données brutes<br/>
    rect = CGRect((left, top), (width, height))<br/>
    image = CGWindowListCreateImage(<br/>
                rect, kCGWindowListOptionOnScreenOnly,<br/>
                kCGNullWindowID, kCGWindowImageDefault)<br/>
<br/>
    # Enregistrement<br/>
    url = NSURL.fileURLWithPath_(filename)<br/>
    dest = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, None)<br/>
    properties = {<br/>
        kCGImagePropertyDPIWidth: dpi,<br/>
        kCGImagePropertyDPIHeight: dpi,<br/>
    }<br/>
    CGImageDestinationAddImage(dest, image, properties)<br/>
    if CGImageDestinationFinalize(dest):<br/>
        print('Fichier {0} créé.'.format(filename))<br/>
</code></pre>
L'option <code class="language-python">kCGWindowListOptionOnScreenOnly</code> permet de ne créer une image que de ce qui est affiché à l'écran. Elle permet de ne pas avoir une image improbable lorsqu'on récupère les dimensions via <code class="language-python">CGRectInfinite</code>.<br/>
<br/>
<hr />
<h3 id="main">Boucle générale</h3>
<br/>
Plus court, tu meurs&nbsp;:<br/>
<pre><code class="language-python">if __name__ == '__main__':<br/>
    # Une capture par écran<br/>
    i = 1<br/>
    for monitor in enum_display_monitors():<br/>
        filename = 'mss-capture-{0}.png'.format(i)<br/>
        get_pixels_and_save(monitor, filename)<br/>
        i += 1<br/>
<br/>
    # Capture complète<br/>
    monitor = enum_display_monitors(oneshot=True)[0]<br/>
    filename = 'mss-capture-complet.png'<br/>
    get_pixels_and_save(monitor, filename)<br/>
</code></pre>
<br/>
Voici le <a href="http://tiger-222.fr/files/mss-darwin.py">script complet</a>, et la <a href="media/711447b7.mss-capture-2-mac.jpg" data-original-source="http://tiger-222.fr/img/mss-capture-2-mac.jpg">capture d'écran</a> (merci à Eownis).<br/>
<br/>
<hr />
<h2 id="bonus">Bonus</h2>
<br/>
J'ai mis en place une <a href="https://tiger-222.fr/tout/python-mss/galerie/">galerie d'images</a> afin d'exposer les captures d'écran <span style="font-style: italic;">oneshot</span> que vous me ferez parvenir ☺<br/>
<br/>
<hr />
<h2 id="sources">Sources diverses</h2>
<br/>
<ul>
<li><a href="https://developer.apple.com/library/mac/documentation/GraphicsImaging/Conceptual/QuartzDisplayServicesConceptual/">Quartz Display Services Programming Topics</a></li>
<li><a href="https://developer.apple.com/library/mac/qa/qa1741/_index.html">How to take an image snapshot of the screen on Mac OS X Lion</a></li>
<li><a href="http://neverfear.org/blog/view/156/OS_X_Screen_capture_from_Python_PyObjC">OS X Screen capture from Python/PyObjC</a></li>
<li><a href="http://stackoverflow.com/questions/4524723/take-screenshot-in-python-on-mac-os-x">osx - Take screenshot in Python on Mac OS X - Stack Overflow</a></li>
</ul>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130830223059
title: Z Shell, le shell qui déchire
uri: Mémo-Avoir-un-shell-qui-déchire
url: https://tiger-222.fr/?d=2013/08/30/22/30/59-z-shell-le-shell-qui-dechire
content:
<a href="http://www.zsh.org/">Zsh</a> est donc un <a href="https://fr.wikipedia.org/wiki/Shell_%28informatique%29">shell</a>, tout comme <a href="https://fr.wikipedia.org/wiki/Bourne_shell">sh</a>, <a href="https://fr.wikipedia.org/wiki/Bourne-Again_shell">bash</a> ou <a href="https://fr.wikipedia.org/wiki/Debian_Almquist_shell">dash</a>. Zsh apporte un lot considérable d'améliorations au shell de base, notamment&nbsp;:<br/>
<ul>
<li>la <a href="https://fr.wikipedia.org/wiki/Compl%C3%A8tement">complétion</a> des commandes, des options et des arguments de la plupart des commandes</li>
<li>une invite de commande personnalisable</li>
<li><a href="https://fr.wikipedia.org/wiki/Z_shell#Fonctionnalit.C3.A9s">et tout un tas d'autres choses fortes intéressantes</a></li>
</ul>
<div style="text-align:center;"><img src="media/fd84fedd.zsh.png" data-original-source="http://tiger-222.fr/img/zsh.png" alt="Aperçu de zsh" /></div><br/>
<hr />
<h2>Installation</h2>
<br/>
Pour faire au plus simple, voici les quelques lignes à taper dans un terminal pour l'installation et la configuration du Z Shell&nbsp;:<br/>
<pre><code class="language-bash"># À adapter suivant votre distribution, ici pour celles basées sur Debian&nbsp;:<br/>
$ aptitude install zsh<br/>
<br/>
# Pour tout le monde<br/>
$ wget --no-check-certificate <a href="https://tiger-222.fr/files/zsh.tar">https://tiger-222.fr/files/zsh.tar</a><br/>
$ tar -xf zsh.tar<br/>
$ rm  zsh.tar<br/>
$ mv -f zshenv zshrc zlogout /etc/zsh<br/>
<br/>
# Changement de shell pour l'utilisateur courant&nbsp;:<br/>
$ chsh<br/>
# Entrez /bin/zsh puis déconnectez-vous.<br/>
</code></pre>
<br/>
Et voilà&nbsp;! Un shell bien chiadé, tout beau, tout neuf ❤


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130912232347
title: Shaarlimages.net
uri: Shaarlimages-net
url: https://tiger-222.fr/?d=2013/09/12/23/23/47-shaarlimagesnet
content:
<div style="text-align:center;"><img src="media/be13e987.shaarlimages.jpg" data-original-source="http://tiger-222.fr/img/shaarlimages.jpg" alt="shaarlimages.jpg" /></div><br/>
Suite à <a href="http://sebsauvage.net/paste/?b1176a415f9bbe17#CIT+sEj+1tsMW8IAWBipoVJiNBcgLt81Gm79rxuiVnU">cette requête</a>, je me suis penché sur le sujet. Après quelques recherches et bidouillages de codes, je vous présente <a href="http://shaarlimages.net">Shaarlimages</a>&nbsp;! Pour l'occasion, j'ai réservé le nom de domaine, mais si quelqu'un d'autre le veut, je pourrai le céder facilement ☺. <br/>
<br/>
Le but était d'avoir une galerie qui soit d'un niveau proche de celle de <a href="http://www.chromatic.io/FQrLQsb">Chromatic.io</a>. Je me suis imposé de ne pas utiliser de bibliothèques tierces telles que jQuery ou Prototype ; c'est du donc du javascript natif. Les sources de chromatic.io étant relativement obfusquées (quelle merde ce cloud d'Amazon...), je me suis largement inspiré du projet de <a href="http://www.jakobholmelund.com/">Jakob Holmelund</a>&nbsp;: <a href="https://github.com/jakobholmelund/fitpicsjs">fitpicjs</a>, un grand merci à ce brave homme&nbsp;!<br/>
<br/>
<hr />
<h2>La démo</h2>
<br/>
C'est sur <a href="http://shaarlimages.net">Shaarlimages.net</a> que ça se passe. Il est possible de filtrer par date en ajoutant à l'URL le paramètre <span style="font-weight: bold;">d</span>&nbsp;: <code class="language-js">?d=aaaammdd</code>, exemple avec la journée du <a href="http://shaarlimages.net/?d=20130908">8 août 2013</a>.<br/>
<br/>
Par défaut, si le tag NSFW (<a href="https://fr.wikipedia.org/wiki/Not_Safe_for_Work">Not Safe for Work</a>) est trouvé dans la catégorie, le titre ou la description, l'image sera alors presque invisible. En cliquant dessus, par contre, l'image ne sera pas filtrée. Il est possible de désactiver ce filtrage en passe le paramètre <code class="language-php">$CONFIG['show_nsfw']</code> à <span style="font-weight: bold;">true</span>.<br/>
<br/>
Je me sers du fichier d'export de <a href="http://shaarli.fr/opml?mod=opml">shaarli.fr</a> pour récupérer la liste des shaarlis à parser, donc si vous souhaitez ajouter le vôtre, <a href="https://tiger-222.fr/mailto:contact@shaarli.fr">envoyez un p'tit mot</a>.<br/>
<br/>
<hr />
<h2>Téléchargement</h2>
<br/>
Le code du site entier est sur <a href="https://github.com/BoboTiG/shaarlimages">GitHub</a>, faites-vous plaisir&nbsp;!<br/>
<br/>
<hr />
<h2>Plus d'informations ?</h2>
<br/>
La galerie utilise le système de partition linéaire, c'est-à-dire perdre le moins d'espace possible. Les images sont redimensionnées pour qu'une quantité correcte soit affichée par ligne, et ce de façon agréable visuellement ☂. L'article <a href="http://www.crispymtn.com/stories/the-algorithm-for-a-perfectly-balanced-photo-gallery">The algorithm for a perfectly balanced photo gallery</a> (en anglais) explique un peu plus en détails le principe.<br/>
Lors d'un clic sur une image, l'affichage est important&nbsp;: l'image prend le maximum d'espace sur l'écran et la couleur de fond est adaptée à chacune d'entre elles. J'utilise une fonction PHP pour déterminer la couleur dominante moyenne&nbsp;:<br/>
<br/>
<pre><code class="language-php">function docolav($fichier) {<br/>
    list($width, $height, $type) = getimagesize($fichier);<br/>
    if ( $type == 2 ) {  // jpeg<br/>
        $img = imagecreatefromjpeg($fichier);<br/>
    } elseif ( $type == 3 ) {  // png<br/>
        $img = imagecreatefrompng($fichier);<br/>
    } else {<br/>
        return NULL;<br/>
    }<br/>
    <br/>
    // <a href="http://stackoverflow.com/questions/6962814/average-of-rgb-color-of-image">http://stackoverflow.com/questions/6962814/average-of-rgb-color-of-image</a><br/>
    $tmp_img = ImageCreateTrueColor(1, 1);<br/>
    ImageCopyResampled($tmp_img, $img, 0, 0, 0, 0, 1, 1, $width, $height);<br/>
    $rgb = ImageColorAt($tmp_img, 0, 0);<br/>
    $r = ($rgb >> 16) & 0xFF;<br/>
    $g = ($rgb >> 8) & 0xFF;<br/>
    $b =  $rgb & 0xFF;<br/>
<br/>
    unset($rgb);<br/>
    imagedestroy($tmp_img);<br/>
    imagedestroy($img);<br/>
    return sprintf('%02X%02X%02X', $r, $g, $b);<br/>
}</code></pre>
<br/>
Ce code est relativement rapide (bien plus que ma version <a href="https://github.com/BoboTiG/docolav">C++</a> d'ailleurs...), on demande à redimensionner l'image à 1x1 pixel, tout en gardant l'échantillonnage des couleurs&nbsp;: donc calcul de la couleur moyenne dominante pour savoir quelle sera la couleur de ce seul pixel. Bien pensé et diablement plus efficace que parcourir tous les pixels <span style="font-style: italic;">à la main</span>.<br/>
<br/>
De plus, si vous avez compris le code, vous aurez requarqué que seuls les formats d'image <span style="font-weight: bold;">JPEG</span> et <span style="font-weight: bold;">PNG</span> sont pris en compte. D'autres seront à venir suivant la demande (hormis pour les images animées).<br/>
<br/>
<hr />
<h2>Pour les développeurs</h2>
<br/>
Avant tout, sachez que ce n'est pas <a href="media/c57f044b.LamerC3A0boire.jpg" data-original-source="https://lh3.ggpht.com/_fj2b1WHMejM/S82K2JtAcRI/AAAAAAAABKE/6NequAUoMTM/s1600/La+mer+%C3%A0+boire.jpg">la mer à boire</a>&nbsp;: 3.2 ko (CSS) + 3.1 ko (JS) = <span style="font-weight: bold;">6.3 ko</span>&nbsp;!<br/>
<br/>
Ensuite, Shaarlimages est un exemple, mais pour ceux qui veulent utiliser le même système ailleurs, voici comment faire. Dans votre code, il faut définir un conteneur avec l'ID <code class="language-markup">image-container</code>. Dans ce conteneur, chaque image doit être encadrée dans une <code class="language-markup">figure</code>. Puis incluez le code <a href="https://raw.github.com/BoboTiG/shaarlimages/master/assets/js/linear-partition.min.js">javascript</a> en bas de page, ça devrait être bon.<br/>
<br/>
Exemple&nbsp;:<br/>
<pre><code class="language-markup">&lt;div id="image-container">
	&lt;figure><br/>
		&lt;a href="media/00a3687b." data-original-source="https://tiger-222.fr/">&lt;img src="media/084d514f.image.jpg" data-original-source="https://tiger-222.fr/images/image.jpg">&lt;/a><br/>
	&lt;/figure><br/>
<br/>
	&lt;!-- Un exemple avec une image sensible (NSFW) --><br/>
	&lt;figure data="nsfw"><br/>
		&lt;a href="media/00a3687b." data-original-source="https://tiger-222.fr/">&lt;img src="media/df2ddecb.image-trop-sexy.jpg" data-original-source="https://tiger-222.fr/images/image-trop-sexy.jpg">&lt;/a><br/>
	&lt;/figure><br/>
&lt;/div><br/>
<br/>
&lt;script async src="https://tiger-222.fr/linear-partition.min.js">&lt;/script></code></pre>
Pensez aussi à include le <a href="https://raw.github.com/BoboTiG/shaarlimages/master/assets/css/main.min.css">fichier CSS</a>.<br/>
<br/>
<hr />
<h2>Améliorations possibles</h2>
<br/>
Dans l'immédiat, la couleur de fond pour chaque image est calculée (couleur moyenne dominante) et une image est ajoutée par dessus pour le grain. Bien que ça ne rende pas trop mal, il faudrait revoir le mécanisme pour se rapprocher un peu plus de <a href="http://www.chromatic.io/FQrLQsb">cette galerie</a> (qui utilise des <a href="https://tiger-222.fr/paste/?70473f0d092aaa05#cGklTL090mJ92ZejuDBP6RvjfEno7yjQzjqaFqWQIDk=">images</a>).<br/>
<br/>
Éventuellement, trouver un service en ligne, ou un code PHP, permettant de compresser les images (progressif pour le JPEG, et optimisations générales).<br/>
<br/>
Pour le reste, libre à vous de forker, bidouiller et proposer des patches ☺


feed_id: https://tiger-222.fr/index.php?mode=links&id=20130920015726
title: Shaarlimages reloaded !
uri: Shaarlimages-reloaded
url: https://tiger-222.fr/?d=2013/09/20/01/57/26-shaarlimages-reloaded
content:
<div style="text-align:center;"><img src="media/88851ef9.shaarlimages-3.jpg" data-original-source="http://tiger-222.fr/img/shaarlimages-3.jpg" alt="Shaarlimages.net" /></div><br/>
<a href="http://shaarlimages.net/">Shaarlimages.net</a> a subi des débuts assez chaotiques, j'avoue, mais il faut savoir vivre dans le danger&nbsp;!<br/>
Pour vous en mettre plein la vue, <a href="http://shaarlimages.net/?i=9VHeaQ">jettez un œil à cette image</a>, et utilisez les flèches gauche & droite pour aller à la précendente & suivante... ❤<br/>
Bref, suite à de nombreux retours, tous positifs, voici quelques informations.<br/>
<br/>
<hr />
<h2>Changements</h2>
<br/>
Étant donné que la base était assez légère, il n'y a pas grand chose de changé, hormis la couleur de fond de la galerie qui est passée à <code class="language-css">#EEEEEE</code>.<br/>
Le système de la galerie a été entièrement réécrit en JS/CSS/HTML, plus de PHP. Ça permettra d'avoir des galeries sur clefs USB ou des serveurs sans PHP (ça existe encore ?). D'ailleurs, pour ceux qui veulent s'approprier juste le système, reportez-vous au dépôt <a href="https://github.com/BoboTiG/galinear">Galinear</a> (je le mettrai à jour une fois que j'aurai quelque chose de plus facile à intégrer).<br/>
<span style="color:teal;">MàJ du 2013-09-23</span>&nbsp;: utilisation de la liste des shaarlis de <a href="https://nexen.mkdir.fr/shaarli-api/feeds?pretty=1">Shaarli Flux River</a>, plus complète.<br/>
<span style="color:teal;">MàJ du 2013-09-26</span>&nbsp;: amélioration notable lors de la récupération des liens et création de thumbnails pour alléger les pages.<br/>
<span style="color:teal;">MàJ du 2013-09-27</span>&nbsp;: refonte du code, tout est paramétrable dans <span style="font-style: italic;">inc/Config.php</span>.<br/>
<br/>
<hr />
<h2>Nouveautés</h2>
<br/>
Ou plutôt devrais-je dire&nbsp;: <span style="font-style: italic;">fonctionnalités de base que je n'avais pas encore implémentées</span>...<br/>
<br/>
<ul>
<li>ajout du <a href="http://shaarlimages.net/?do=rss">flux RSS</a>, avec possibilité de filtrer le nombre d'entrées à l'aide du paramètre <span style="font-weight: bold;">n</span>&nbsp;: <a href="http://shaarlimages.net/?do=rss&n=10">do=rss&n=10</a></li>
<li>ajout des fléches de navigation</li>
<li>prise en charge des flèches du clavier (gauche et droite) pour naviguer dans les images ou les pages</li>
<li>ajout d'une barre d'icônes avec quelques liens (retour à l'accueil, lien du shaarlieur et l'image originale)</li>
<li>tous les textes sont traduisibles</li>
<li>un petit bandeau NSFW pour les images sensibles</li>
<li>ajout des icônes iPhone/iPad (police <a href="http://www.dafont.com/fr/comic-andy.font">Comic Andy</a>, la même que celle de <a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli">shaarli</a>)</li>
<li>une 1<sup>ère</sup> tentative de chargement des images, mais ce n'est pas encore ça...</li>
<li>pour certains noms de domaine, tel que <a href="http://imgur.com">Imgur</a>, qui n'affichent pas directement l'image, et grâce à une API, le script s'occupe de récupérer le bon lien (facile à mettre en place, voyez la classe <span style="font-style: italic;">inc/Solver.php</span>)</li>
<li>et j'avais oublié de préciser&nbsp;: le <span style="text-decoration: underline;">design est responsive</span>&nbsp;!</li>
<li><span style="color:teal;">MàJ du 2013-09-20</span>&nbsp;: le filtrage par date fonctionne entièrement en JS&nbsp;: <a href="http://shaarlimages.net/?d=20130915">d=20130915</a></li>
<li><span style="color:teal;">MàJ du 2013-09-20</span>&nbsp;: ajout de <span style="font-style: italic;">Solver::flickr</span></li>
<li><span style="text-decoration: line-through;"><span style="color:teal;">MàJ du 2013-09-23</span>&nbsp;: ajout de <span style="font-style: italic;">Solver::cheezburger</span></span> (la récupération du token demande d'être inscrit)</li>
<li><span style="color:teal;">MàJ du 2013-09-25</span>&nbsp;: ajout de <span style="font-style: italic;">Solver::xkcd</span> et <span style="font-style: italic;">Solver::twitter</span></li>
<li><span style="color:teal;">MàJ du 2013-09-25</span>&nbsp;: prise en compte de l'extension de fichier <span style="font-style: italic;">.jpeg</span></li>
<li><span style="color:teal;">MàJ du 2013-09-26</span>&nbsp;: ajout de <span style="font-style: italic;">Solver::cheezburger</span>, seulement pour les liens en <span style="font-style: italic;">http://i.chzbgr.com</span></li>
<li><span style="color:teal;">MàJ du 2013-09-26</span>&nbsp;: la galerie est pilotable par glissage de doigts ★ (<a href="https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Events/Touch_events">touch events inside</a>)</li>
<li><span style="color:teal;">MàJ du 2013-09-27</span>&nbsp;: ajout de <span style="font-style: italic;">Solver::luc</span> (avec l'autorisation du <a href="http://www.luc-damas.fr/humeurs/">prof</a>)</li>
<li><span style="color:teal;">MàJ du 2013-09-28</span>&nbsp;: ajout de <span style="font-style: italic;">Solver::deviantart</span> et <span style="font-style: italic;">Solver::bonjourmadame</span></li>
<li><span style="color:teal;">MàJ du 2013-09-28</span>&nbsp;: ajout de l'<a href="https://en.wikipedia.org/wiki/Ambilight">effet ambilight</a>, activé par défaut</li>
<li><span style="color:teal;">MàJ du 2013-09-30</span>&nbsp;: ajout du panneau de préférences par cookies, caché en haut à gauche, avec la prise en compte des paramètres <code class="language-markup">toolbar</code>, <code class="language-markup">show_nsfw</code> et <code class="language-markup">al</code>)</li>
<li><span style="color:teal;">MàJ du 2013-10-01</span>&nbsp;: ajout de <span style="font-style: italic;">Solver::googleusercontent</span> et <span style="font-style: italic;">Solver::commitstrip</span> (avec l'autorisation des <a href="http://www.commitstrip.com/">codeurs</a>)</li>
<li><span style="color:teal;">MàJ du 2013-10-04</span>&nbsp;: ajout de <span style="font-style: italic;">Solver::tumblr</span></li>
</ul>
J'ai mis le paquet sur la possibilité de personnaliser l'affichage. Les paramètres par défaut peuvent être modifiés soit en passant par l'URL, soit en utilisant le petit panneau en haut à gauche, qui utilise les cookies pour que ça soit permanent. Les différents paramètres sont&nbsp;:<br/>
<br/>
<ul>
<li><code class="language-markup">per_page</code> => <span style="font-weight: bold;">N</span> &nbsp;: afficher N images par pages (minimum&nbsp;: 10, par défaut&nbsp;: 20, maximum&nbsp;: aucun)</li>
<li><code class="language-markup">lines</code> => <span style="font-weight: bold;">N</span> &nbsp;: afficher de préférence N rangées d'images à l'écran, faites des tests ça peut rendre vachement bien suivant votre résolution (minimum&nbsp;: 2, par défaut&nbsp;: 3, maximum&nbsp;: aucun)</li>
<li><code class="language-markup">toolbar</code> => <span style="font-weight: bold;">1</span> ou 0&nbsp;: afficher/cacher la barre d'icônes</li>
<li><code class="language-markup">show_nsfw</code> => <span style="font-weight: bold;">0</span> ou 1&nbsp;: filtrer ou non les images sensibles (se base sur les tags)</li>
<li><code class="language-markup">al</code> => 0 ou <span style="font-weight: bold;">1</span>&nbsp;: utiliser ou non l'effet ambilight</li>
</ul>
Un gros travail a été fait pour rendre le code plus agréable et facile à étudier. Je me suis pas mal inspiré des projets <a href="https://github.com/tontof/kriss_feed">KrISS feed</a> (vraiment propre, c'est du joli&nbsp;!) et <a href="http://nexen.mkdir.fr/shaarli-river/">Shaarli Flux River</a> (pour la classe RSS).<br/>
<br/>
<hr />
<h2>Futur</h2>
<br/>
<a href="https://tiger-222.fr/index.php?d=2013/09/12/23/23/47-#id852e3e">Ketluts</a> a proposé d'utiliser un fond <a href="http://ketluts.net/zepixDemo/?t=JnHTTOsNqR">ambiligth</a> plutôt qu'une couleur moyenne&nbsp;: je regarderai ça plus tard, ça pourra être une option d'affichage, en tout cas, ça rend bien. (OK, <span style="color:teal;">MàJ du 2013-09-28</span>, d'autres informations sur cette page&nbsp;: <a href="http://chikuyonok.ru/2010/03/ambilight-video/">Ambilight для тэга video</a>)<br/>
<br/>
La prise en compte des évènements de toucher pour les smartphones (faire glisser un doigt pour changer d'image ou de page). (OK, <span style="color:teal;">MàJ du 2013-09-26</span>)<br/>
<br/>
Et la mise en place d'une API pour faire toute sorte de recherches.<br/>
<br/>
Sur certains site web, l'accès est difficile. Par exemple pour le <a href="http://sameganegie.biz/shaarli/">Shaarli de Sam Ganegie</a>, j'ai plus souvent cette erreur que le flux&nbsp;: <span style="font-style: italic;">Access denied | sameganegie.biz used CloudFlare to restrict access</span>. Sur celui du <a href="http://www.warriordudimanche.net/shaarli/">Warrior du Dimanche</a>, idem, c'est à la roulette russe, j'ai une restriction comme quoi mon adresse IP est cataloguée en SPAM. Il faut trouver une parade.<br/>
<br/>
<hr />
<h2>Appel de détresse</h2>
<br/>
Avec tous les services qui se font autour de shaarli (<a href="https://www.ecirtam.net/shaarlirss/">Flux RSS des Shaarlis</a> -- 102 liens, <a href="http://shaarli.fr">Shaarlo</a> -- 105 liens, <a href="http://nexen.mkdir.fr/shaarli-river/">Shaarli Flux River</a> -- 111 liens et <a href="http://nexen.mkdir.fr/shaarli-tv/">ShaarliTV</a>), il serait fort intéressant d'avoir un seul fichier OPML contenant les différents shaarlis actifs. J'utilise celui de <a href="http://shaarli.fr/opml?mod=opml">Shaarlo</a>, mais il y a déjà deux flux HS. Ça vous tente de regrouper vos URL vers Shaarlo ? Ou autre part, je ne suis pas casse-pied. ☺<br/>
<br/>
<span style="color:teal;">MàJ du 2013-09-26</span>&nbsp;: mon appel a été entendu&nbsp;! Voici une <a href="https://shaarlo.fr/shaarli/?jDLqzg">1<sup>ère</sup> réponse</a> et des <a href="http://gilles.wittezaele.fr/paste/?ddd3e93511c383a9#NV/SqqjXIfzY03rVmOe5cn0/AFPqTmrR9Q11u93WsCA=">idées pour un annuaire de Shaarlis</a> (n'hésitez pas à participer, tous les avis sont bons à prendre).


feed_id: https://tiger-222.fr/index.php?mode=links&id=20131014173215
title: PHP : is_file vs file_exists
uri: PHP-is_file-vs-file_exists
url: https://tiger-222.fr/?d=2013/10/14/17/32/15-php-is_file-vs-file_exists
content:
<a href="http://us2.php.net/manual/fr/function.is-file.php">is_file</a>, comme la documentation l'indique, vérifie si le fichier est un véritable fichier, tandis que <a href="http://php.net/manual/fr/function.file-exists.php">file_exists</a> vérifie si un fichier ou un dossier existe. À savoir que ces deux fonctions utilisent <a href="http://www.php.net/manual/fr/function.clearstatcache.php">un système de cache</a>, elles partent donc sur un pied d'égalité.<br/>
<hr>
<h2 id="sources">Les sources</h2>
<br/>
Rien de mieux que le retour aux <a href="https://github.com/php/php-src/">sources</a> pour voir les entrailles de ces deux fonctions. Il s'avère qu'elles utilisent la même function en interne, seules les routines de vérification diffèrent.<br/>
<br/>
Ci-dessous, le pseudo code <span style="font-style: italic;">très simplifié</span> du processus de vérification&nbsp;:<br/>
<pre><code class="language-php">function php_stat($fichier)<br/>
{<br/>
    'file_exists'<br/>
        ↳ virtual_file_ex($fichier)<br/>
            ↳ virtual_access($fichier)<br/>
                'Windows'<br/>
                    ↳ tsrm_win32_access($fichier)<br/>
                        ↳ return access($fichier)<br/>
                'Autres systèmes'<br/>
                    ↳ return access($fichier)<br/>
        ↳ return _php_stream_stat_path($fichier) == FALSE<br/>
    'is_file'<br/>
        ↳ _php_stream_stat_path($fichier)<br/>
            ↳ return $fichier.st_mode == S_IFREG<br/>
}</code></pre>
<br/>
Pour les curieux, voici les sources des fonctions&nbsp;:<br/>
<ul>
<li><a href="https://github.com/php/php-src/blob/master/ext/standard/filestat.c#L849">php_stat</a></li>
<li><a href="https://github.com/php/php-src/blob/master/TSRM/tsrm_virtual_cwd.c#L1151">virtual_file_ex</a></li>
<li><a href="https://github.com/php/php-src/blob/master/TSRM/tsrm_virtual_cwd.c#L1488">virtual_access</a></li>
<li><a href="https://github.com/php/php-src/blob/master//TSRM/tsrm_win32.c#L193">tsrm_win32_access</a></li>
<li><a href="https://www.gnu.org/software/libc/manual/html_node/Testing-File-Access.html">access</a> fait partie de la <a href="http://fr.wikipedia.org/wiki/Biblioth%C3%A8que_standard_de_C">libc</a></li>
<li><a href="https://github.com/php/php-src/blob/master/main/streams/streams.c#L1912">_php_stream_stat_path</a> (c'est ici qu'on vérifie le cache)</li>
<li>et <a href="http://www.php.net/manual/fr/function.stat.php#34919">S_IFREG</a> est la constante des fichiers réguliers<br/>
</ul>
Au premier abor, ça semble <a href="media/ca4a9f66.clair-comme-eau-de-roche.jpg" data-original-source="http://tiger-222.fr/img/clair-comme-eau-de-roche.jpg">clair comme de l'eau de roche</a>, <code class="language-php">file_exists()</code> nécessite bien plus d'opérations à effectuer. Cependant, <code class="language-php">_php_stream_stat_path()</code> est lourde puisqu'elle récupère toutes les informations sur un fichier/dossier (appelé <span style="font-weight: bold;">inode</span>)&nbsp;: volume, numéro d'inode, droit d'accès à l'inode, nombre de liens, userid du propriétaire, groupid du propriétaire, type du volume, si le volume est une inode, taille en octets, date de dernier accès (Unix timestamp), date de dernière modification (Unix timestamp), date de dernier changement d'inode (Unix timestamp), taille de bloc et le nombre de blocs de 512 octets alloués.<br/>
<br/>
Il faudra attendre de voir le résultat des tests pour se faire une meilleure idée.<br/>
<br/>
<hr />
<h2 id="stream">Une meilleure alternative ?</h2>
<br/>
Dans ce <a href="http://www.php.net/manual/fr/function.file-exists.php#107191">commentaire</a>, DeyV laisse à penser que <a href="http://php.net/manual/fr/function.stream-resolve-include-path.php">stream_resolve_include_path</a> serait une bonne alternative à <code class="language-php">file_exists()</code>. À priori, cette fonction <a href="http://www.php.net/manual/en/function.stream-resolve-include-path.php#111790">utiliserait aussi le système de cache</a>.<div style="text-align:center;"><q>Great alternative to file_exists() is stream_resolve_include_path()  -- <span style="font-weight: bold;">DeyV</span><br/>
</q></div>Toujours d'après les sources, le pseudo code suivant en ressort&nbsp;:<br/>
<pre><code class="language-php">function stream_resolve_include_path($fichier)<br/>
{<br/>
    zend_resolve_path($fichier)<br/>
        ↳ php_resolve_path_for_zend($fichier)<br/>
            ↳ php_resolve_path($fichier)<br/>
                ↳ tsrm_realpath($fichier)<br/>
                    ↳ return estrdup($fichier)<br/>
}</code></pre>
<br/>
Pour les curieux, le détail de chaque fonction&nbsp;:<br/>
<ul>
<li><a href="https://github.com/php/php-src/blob/master/ext/standard/streamsfuncs.c#L1543">stream_resolve_include_path</a></li>
<li><a href="https://github.com/php/php-src/blob/9529b8f5c48dac70b99bfd2c1def0139c6e93f60/Zend/zend.c#L682">zend_resolve_path</a></li>
<li>(<a href="https://github.com/php/php-src/blob/512734b58dc4e231971901cb87656d67c87e7645/main/main.c#L2036">resolve_path_function</a>)</li>
<li><a href="https://github.com/php/php-src/blob/512734b58dc4e231971901cb87656d67c87e7645/main/main.c#L1368">php_resolve_path_for_zend</a></li>
<li><a href="https://github.com/php/php-src/blob/33c4b61c7f477994d4f30fff349cb1815680642d/main/fopen_wrappers.c#L473">php_resolve_path</a></li>
<li><a href="https://github.com/php/php-src/blob/33c4b61c7f477994d4f30fff349cb1815680642d/TSRM/tsrm_virtual_cwd.c#L750">tsrm_realpath</a></li>
<li>et <a href="http://www.php.net/manual/fr/internals2.memory.management.php">estrdup</a></li>
</ul>
Notez que le fait d'utiliser des chemins absolus permet un gain non négligeable.<br/>
<br/>
<hr>
<h2 id="tests">Les tests</h2>
<br/>
<h3>Configuration de la machine de test</h3>
<ul>
<li>Intel Core i5 CPU 750 @ 2.67GHz</li>
<li>4 Go de RAM</li>
<li>disque dur Seagate STM3500418AS 7200 tr/min</li>
<li>Debian GNU/Linux 7 64 bit</li>
<li>noyau 3.10-3-amd64</li>
<li>système de fichiers EXT4</li>
<li>PHP 5.5.5, options de build&nbsp;: --disable-all --disable-pdo --disable-phar --disable-session --disable-mysqlnd-compression-support --without-pear</li>
</ul>
<hr/>
<h3 id="">Le benchmark</h3>
<br/>
Deux types de tests&nbsp;: un réaliste où on teste la présence de fichiers différents, et un autre moins parlant dans lequel le même fichier est testé 1 000 000 de fois.<br/>
Pour le test réaliste, j'ai créé un dossier <span style="font-style: italic;">test</span> qui contient 1 000 000 fichiers (le premier fichier s'appelant <span style="font-style: italic;">0</span> et le dernier <span style="font-style: italic;">999999</span>).<br/>
D'après le <a href="http://tiger-222.fr/files/php-is_file-vs-file_exists.txt">script</a> qui permet de lancer et chronométrer les tests, le <a href="http://www.chartgo.com/get.do?id=7a227c7634">graphique</a> suivant en résulte&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/3107841a.chartgo-php-is_file_vs_file_exists.png" data-original-source="http://tiger-222.fr/img/chartgo-php-is_file_vs_file_exists.png" alt="" /></div><br/>
<hr />
<h3 id="observations">Observations</h3>
<br/>
<ul>
<li>1&nbsp;: <code class="language-php">is_file()</code> est plus rapide dans tous les cas</li>
<li>2&nbsp;: <code class="language-php">file_exists()</code> a un léger avantage sur <code class="language-php">stream_resolve_include_path()</code>, si ce dernier utilise les chemins absolus</li>
<li>3&nbsp;: <code class="language-php">stream_resolve_include_path()</code> est un gouffre avec les chemins relatifs</li>
</ul>
<hr />
<h2 id="historique">Historique</h2>
<br/>
<span style="color:teal;">MàJ du 2013-10-23</span>&nbsp;: ajout des <a href="https://tiger-222.fr/#sources">explications</a> avec les sources PHP<br/>
<span style="color:teal;">MàJ du 2013-10-25</span>&nbsp;: <a href="https://tiger-222.fr/#stream">Une meilleure alternative ?</a><br/>
<span style="color:teal;">MàJ du 2013-10-27</span>&nbsp;: ajout de <a href="https://tiger-222.fr/#tests">tests plus réalistes</a> et étoffement des informations<br/>
<span style="color:teal;">MàJ du 2013-10-28</span>&nbsp;: ajout du <a href="http://tiger-222.fr/files/php-is_file-vs-file_exists.txt">script de tests</a> pour ne pas trop encombrer la page


feed_id: https://tiger-222.fr/index.php?mode=links&id=20131022005256
title: Déployez vos modules Python
uri: Déployez-vos-modules-Python
url: https://tiger-222.fr/?d=2013/10/22/00/52/56-deployez-vos-modules-python
content:
<div style="text-align:center;"><img src="media/d66dcef7.wallpaper-599753_800.jpg" data-original-source="http://tiger-222.fr/img/wallpaper-599753_800.jpg" alt="Python ou pas, il est vert&nbsp;!" /></div><br/>
Vous venez de terminer votre nouveau module Python&nbsp;! Évidemment, vous l'avez testé dans tous les sens, et souhaitez le déployer <span style="font-style: italic;">vite fait, bien fait</span>. Un module aisément installable, quelque soit le système d'exploitation, est appréciable pour tout le monde ☺<br/>
<br/>
C'est là qu'entre en jeu <a href="https://pypi.python.org/pypi">pip</a>. Je ne rentrerai pas dans les détails du fonctionnement de pip, d'<a href="http://sametmax.com/votre-python-aime-les-pip/">autres les font très bien</a>. Je m'attarderai plutôt sur la création des fichiers nécessaires ainsi que l'envoi au serveur.<br/>
Pour les pressés, voici un mémo des commandes&nbsp;:<br/>
<pre><code class="language-bash">$ python setup.py register<br/>
$ python setup.py sdist upload</code></pre>
<br/>
<hr>
<h2 id="base">Préparer la base</h2>
<br/>
Vous avez sûrement déjà vu un de ces fameux <code class="language-markup">setup.py</code>, et bien c'est lui qui gère tout. Vous pouvez voir les projets <a href="https://github.com/BoboTiG/python-mss">MSS</a> ou <a href="https://github.com/sametmax/minibelt">minibelt</a> pour vous en inspirer ; voici un exemple tiré du module <a href="https://tiger-222.fr/index.php?d=2013/07/01/22/34/59-module-python-multi-screen-shot">MSS</a>&nbsp;:<br/>
<pre><code class="language-python"># Import du bon module de gestion<br/>
try:<br/>
    from distutils.core import setup<br/>
except ImportError:<br/>
    from setuptools import setup<br/>
<br/>
# Dans le fichier MANIFEST.in, on y liste les ficihers et dossiers à inclure (ou pas)<br/>
# dans l'archive qui sera déployée.<br/>
# Par défaut, seuls les fichiers module.py et setup.py sont inclus.<br/>
open('MANIFEST.in', 'w').write('\n'.join((<br/>
    "include *.rst",<br/>
    # un_dossier/*.py<br/>
    # un_autre_fichier.py<br/>
    # prune archives/  &lt;-- ne pas inclure le dossier archives<br/>
)))<br/>
<br/>
# En option, importez la version de votre module<br/>
from mss import __version__<br/>
<br/>
# Le nom des clefs est assez explicite, on renseigne les infos principales du module<br/>
setup(<br/>
    name='mss',<br/>
    version=__version__,<br/>
    author='Tiger-222',<br/>
    py_modules=['mss'],<br/>
    author_email='contact@tiger-222.fr',<br/>
    description='A cross-platform multi-screen shot module in pure python using ctypes',<br/>
    long_description=open('README.rst').read(),<br/>
    classifiers=[<br/>
        'Programming Language&nbsp;:: Python',<br/>
        'Intended Audience&nbsp;:: Developers',<br/>
        'Intended Audience&nbsp;:: Information Technology',<br/>
        'License&nbsp;:: OSI Approved&nbsp;:: zlib/libpng License',<br/>
        'Natural Language&nbsp;:: English',<br/>
        'Programming Language&nbsp;:: Python&nbsp;:: 2.7',<br/>
        'Programming Language&nbsp;:: Python&nbsp;:: 3.3',<br/>
        'Topic&nbsp;:: Multimedia&nbsp;:: Graphics&nbsp;:: Capture&nbsp;:: Screen Capture',<br/>
    ],<br/>
    url='<a href="https://github.com/BoboTiG/python-mss">https://github.com/BoboTiG/python-mss</a>'<br/>
)</code></pre>
Vous aurez remarquer la présence d'un certain <span style="font-style: italic;">README.rst</span> (format <a href="https://fr.wikipedia.org/wiki/ReStructuredText">ReStructuredText</a>), il s'agit de la description complète du module (ses classes et méthodes, exemples, ...).<br/>
La liste des <span style="font-weight: bold;">classifiers</span> se trouve ici&nbsp;: <a href="https://pypi.python.org/pypi?%3Aaction=list_classifiers">List trove classifiers</a>.<br/>
<br/>
En passant, GitHub accepte les fichiers README.rst, pratique&nbsp;! Et voici une visionneuse de fichiers RST&nbsp;: <a href="http://mg.pov.lt/restview/">restview</a>.<br/>
<br/>
<hr>
<h2 id="deployer">Le déploiement</h2>
<br/>
<h3 id="creation">Créer le dépôt</h3>
<br/>
Ouvrez une console, rendez-vous dans le répertoire du projet, puis&nbsp;:<br/>
<pre><code class="language-bash">$ python setup.py register<br/>
running register<br/>
running check<br/>
We need to know who you are, so please choose either:<br/>
 1. use your existing login,<br/>
 2. register as a new user,<br/>
 3. have the server generate a new password for you (and email it to you), or<br/>
 4. quit<br/>
Your selection [default 1]:</code></pre>
Si vous n'avez pas encore de compte, prenez l'option 2, sinon la 1.<br/>
<br/>
Si tout s'est bien passé, vous devriez avoir ce genre de message&nbsp;:<br/>
<pre><code class="language-bash">Registering mss to <a href="http://pypi.python.org/pypi">http://pypi.python.org/pypi</a><br/>
Server response (200): OK</code></pre>
<br/>
Voilà, votre <a href="https://pypi.python.org/pypi?:action=display&name=mss">module est en ligne</a>&nbsp;!<br/>
<br/>
<hr />
<h3 id="envoi">Envoyer le module</h3>
<br/>
La page du module a été créée, mais aucun fichier n'est disponible en téléchargement. Cette commande génère une archive puis l'envoie au serveur&nbsp;:<br/>
<pre><code class="language-bash">$ python setup.py sdist upload<br/>
running sdist<br/>
running check<br/>
warning: sdist: standard file not found: should have one of README, README.txt<br/>
<br/>
reading manifest template 'MANIFEST.in'<br/>
writing manifest file 'MANIFEST'<br/>
creating mss-0.0.2<br/>
making hard links in mss-0.0.2...<br/>
hard linking README.rst -> mss-0.0.2<br/>
hard linking mss.py -> mss-0.0.2<br/>
hard linking setup.py -> mss-0.0.2<br/>
creating dist<br/>
Creating tar archive<br/>
removing 'mss-0.0.2' (and everything under it)<br/>
Submitting dist/mss-0.0.2.tar.gz to <a href="http://pypi.python.org/pypi">http://pypi.python.org/pypi</a><br/>
Upload (200): OK</code></pre>
Emballé, c'est pesé&nbsp;!<br/>
<br/>
Vous pouvez de suite installer le module fraîchement déployé&nbsp;: <code class="language-shell">pip install mss</code>&nbsp;!<br/>
<br/>
<hr>
<h2 id="sources">Sources</h2>
<ul>
<li><a href="http://docs.python.org/2/distutils/sourcedist.html">4. Creating a Source Distribution &mdash; Python v2.7.5 documentation</a></li>
<li><a href="http://docs.python.org/2/distutils/packageindex.html">6. The Python Package Index (PyPI) &mdash; Python v2.7.5 documentation</a></li>
<li>Photographie venant de Wallbase.cc&nbsp;: <a href="http://wallbase.cc/wallpaper/599753">le serpent vert de chez vert</a> (<a href="media/71972fd2.wallpaper-599753.jpg" data-original-source="http://tiger-222.fr/img/wallpaper-599753.jpg">copie locale</a>)</li>
</ul>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20131026160722
title: TrueCrypt : entretien avec Ennead
uri: TrueCrypt-entretien-avec-Ennead
url: https://tiger-222.fr/?d=2013/10/26/16/07/22-truecrypt-entretien-avec-ennead
content:
<q>Ce qui suit est une traduction libre de l'<a href="http://www.wolfmanzbytes.com/windows/70-truecrypt-encryption.html">entretien</a> d'un des développeurs du logiciel TrueCrypt, Ennead,  par WolfManz611. C'était le samedi 10 septembre 2005.</q><br/>
<h2 id="entrevue">Entetien rare avec Ennead, un des développeurs de TrueCrypt</h2>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Quel est ton rôle au sein du projet <a href="http://www.truecrypt.org/">TrueCrypt</a> ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: J'ai 29 ans et plusieurs casquettes dans ce projet&nbsp;: administrateur, développeur et designer. Je suis aussi responsable de la documentation et du site web.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Combien de temps as-tu passé sur le projet pour en arriver au stade où il est, et combien de développeurs travaillent dessus ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Actuellement, il y a deux développeurs principaux (aussi administrateurs) qui travaillent sur TrueCrypt. Quant à savoir combien de temps nous avons passé sur sur le projet, je dirais beaucoup. Nous avons l'habitude de faire une courte pause après chaque version majeure (à moins qu'il y ait un bogue majeur qui requiert d'être résolu immédiatement) puis commençons à travailler sur la prochaine version. Une partie considérable de notre temps est consacrée à ce projet.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: À quels types d'utilisateurs ce programme est-il destiné ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: C'est une bonne question. Nous essayons constamment d'équilibrer les choses. D'un côté, vous avez les utilisateurs inexpérimentés qui requièrent une prise en main facilitée au maximum, et de l'autre, vous avez les <span style="font-style: italic;">power users</span> qui, quelques fois, demandent des fonctionnalités vraiment obscures, ce qui peut effrayer le communs des mortels. Ce que nous essayons de faire, c'est de trouver le bon compromis qui satisfasse les deux partis.<br/>
<br/>
En outre, il existe des problèmes mono-utilisateur (maison) vs. multi-utilisateurs (société) . Par exemple, les sociétés nous demandent d'implémenter des "portes dérobées" <span style="color:purple;">[NdT&nbsp;: backdoors]</span> dans le cas où un employé oublie son mot de passe, etc. À cet égard, notre logiciel s'adresse plus à des utilisateurs individuels. Malgré cela, d'après les courriels que nous recevons, nous savons qu'il y a beaucoup de sociétés et d'organismes gouvernementaux qui utilisent TrueCrypt.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Est-ce que ce programme prend quelconque contre-mesure pour déjouer les <span style="font-style: italic;">keyloggers</span> ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Actuellement, TrueCrypt n'offre aucune protection active contre les logiciels malveillants. Nous pensons que c'est le rôle du logiciel anti-virus. Pour les <span style="font-style: italic;">keyloggers</span>, la meilleure solution pour les contrer est l'utilisation des fichiers de clef <span style="color:purple;">[NdT&nbsp;: keyfiles]</span>. Nous avons déjà implémenté le support des fichiers de clef et une nouvelle version devrait voir le jour d'ici peu.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Pour donner une idée&nbsp;: en assumant que l'utilisateur ait un mot de passe de 20 caractères aléatoires, à quel point le chiffrement est-il bon en utilisant le type de chiffrement par défaut ? Combien de temps prendrait une tentative de cassage du chiffrement en utilisant une pièce remplie d'ordinateurs haut de gamme ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Je n'ai pas la réponse précise mais je peux donner une estimation. 20 caractères choisis aléatoirement équivaut, en gros, à une clef 128 bit. Disons q'un ordinateur haut de gamme soit capable de tester 100 mots de passes TrueCrypt par seconde. Si nous liions 10 000 ordinateurs de ce même type ensemble, nous pourrions tester 1 000 000 mots de passe par seconde. Par conséquent, il faudrait 5 395 141 535 403 007 094 485 264 années, en moyenne, pour trouver le mot de passe.<br/>
<br/>
Notez que l'estimation ci-dessus n'est valable que si le mot de passe est vraiment aléatoire. S'il s'agit de mots trouvés dans un dictionnaire, noms d'animaux de compagnie, dates d'anniversaire, numéros de téléphone et ainsi de suite, ça pourrait prendre moins de temps pour trouver le mot de passe (l'attaque par force brute peut être optimisée). Il est très important de choisir un bon mot de passe.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: J'ai remarqué que tu peux enregistrer les mots de passe dans le pilote mémoire. Pourquoi les enregistrer là par opposition à la mémoire normale ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Une des raisons est qu'il fallait permettre la mise en cache du mot de passe même quand l'application TrueCrypt se ferme. Le pilote est indépendant de l'application TrueCrypt.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Après un redémarrage ou la mise hors tension de l'ordinateur, le mot de passe dans le pilote mémoire est-il retenu ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Non, le pilote TrueCrypt est arrêté en même temps que Windows.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Penses-tu que plus de programmes actuels, comme les clients de messagerie électronique et similaires, devraient utiliser une sorte de chiffrement sur leurs paramètres et tous les messages qu'ils gèrent ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Oui, bien sûr. De plus en plus de personnes commencent à comprendre que leur vie privée <span style="color:purple;">[NdT&nbsp;: vie intime]</span> est quelque chose qu'ils devraient protéger. Si votre client de messagerie ne supporte pas le chiffrement, il devrait au moins vous permettre de le configurer de telle sorte que tous les fichiers sensibles sur lesquels vous travaillez soient stockés dans un volume TrueCrypt (c-à-d chiffrés à la volée).<br/>
<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Quel est le minimum requis pour que ton programme fonctionne correctement ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Je ne pense pas que TrueCrypt soit très exigeant à cet égard. Il requiert seulement quelques mégaoctets de mémoire vive et environ un mégaoctet d'espace disque.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Avec la recrudescence des vols de données personnelles, ne penses-tu pas que la majorité des gens devrait utiliser un programme comme TrueCrypt afin de tenir les voleurs éloignés ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Eh bien, si le système d'exploitation est infecté, TrueCrypt n'empêchera pas les voleurs d'accéder aux données si un volume TrueCrypt est monté. L'utilisation d'un anti-virus décent est définitivement recommandée.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Travailler sur une version Linux et, si oui, où est-ce que ça en est ? Sera t-elle équivalente à celle de Windows ou meilleure ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Oui, pendant que je travaille sur la version Windows, Syncon fini le travail de la version Linux. Elle était en phase alpha pendant plusieurs semaines et semble très stable.<br/>
<br/>
Initialement, les deux versions ne seront pas égales. Par exemple, il n'y aura pas de GUI pour la version Linux. Cependant, dans un futur proche, les deux versions devraient être équivalentes.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Quelle est la cote de popularité du programme et, à ton avis, combien de personnes l'utiltisent ou l'ont téléchargé ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: D'après les statistiques de SourceForge.net et des <span style="font-style: italic;">log</span> du serveur, à peu près un quart de million de personnes ont téléchargé TrueCrypt 3.1a. Il y a aussi beaucoup d'entités, comme le magazine Chip, qui hébergent nos fichiers sur leurs serveurs, ce qui rend l'estimation impossible.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Dans quel langage de programmation est-il codé ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Le code source est entièrement écrit en C, hormis les routines de l'<a href="https://fr.wikipedia.org/wiki/Serpent_%28cryptographie%29">algorithme de chiffrement Serpent</a>, qui est en assembleur. Vu que notre objectif est de rendre le code multi-plateforme, nous prévoyons de remplacer le code assembleur par du C.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Prévoyez-vous d'implémanter de grosses fonctionnalités et, si oui, quelles sont-elles ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Oui, c'est prévu. Mais ça ne serait plus une surprise si je te le disais&nbsp;!<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Quelle est la problématique du fichier d'échange de Windows pour ce genre de programme ? Est-ce que le fichier d'échange de Windows entre en jeu seulement pour écrire un fichier dans le volume chiffré ou compromet-il les fichiers même lors de la lecture de ceux-ci depuis un volume chiffré ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Chaque fois que vous ouvrez un fichier stocké sur un volume TrueCrypt dans un programme (par exemple, dans un éditeur de texte), une partie du fichier est déchiffré dans la RAM et transmise au programme qui les a demandées. TrueCrypt utilise une réserve <span style="color:purple;">[NdT&nbsp;: pool]</span> non-paginée pour stocker les mots de passe en cache, les clefs de chiffrement, IVs et autres données sensibles relatives au volume, donc ces données ne peuvent pas être divulguées au fichiers de pagination. Cependant, TrueCrypt ne peux prévenir l'accès au contenu déchiffré des fichiers sensibles ouverts en mémoire. Par conséquent, nous recommandons fortement aux utilisateurs de désactiver le fichier d'échange<sup id="1"><a href="https://tiger-222.fr/#pagefile"> 1 </a></sup>, au moins pour chaque session durant laquelle ils travaillent avec des données sensibles.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Prévois-tu de faire d'autres projets qui impliquent le chiffrement, comme un module de client de messagerie facile à utiliser ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: En ce qui concerne le logiciel de chiffrement, nous allons probablement rester avec le modèle de chiffrement de disque à la volée, que nous considérons comme le plus efficace.<br/>
<br/>
<span style="color:#555;"><span style="font-weight: bold;">WolfManz611</span>&nbsp;: Que fait SourceForge.net pour votre programme ? Est-ce qu'il vous donne une bonne exposition et plein de téléchargements ?</span><br/>
<span style="font-weight: bold;">Ennead</span>&nbsp;: Eh bien, j'estime qu'environ 5% des utilisateurs de TrueCrypt l'ont découvert via SourceForge.net. Globalement, les services de SourceForge sont bons, mais il y a des choses qui peuvent être améliorées. Par exemple, la sécurité des services web et les performances des serveurs MySQL sont les raisons pour lesquelles nous avons décidé de migrer le site et les forums sur notre propre serveur dédié.<br/>
<br/>
<hr />
<span id="pagefile"><a href="https://tiger-222.fr/#1">1</a></span> -- Désactiver le fichier de pagination sous <a href="http://www.pcastuces.com/pratique/windows/7/optimiser_ssd/page4.htm">Windows</a>. Pour GNU/Linux&nbsp;:<br/>
<pre><code class="language-bash"># swapoff partition<br/>
sudo swapoff /dev/sda1</code></pre>


feed_id: https://tiger-222.fr/index.php?mode=links&id=20131029122357
title: Git : revoir ses branches
uri: Git-revoir-ses-branches
url: https://tiger-222.fr/?d=2013/10/29/12/23/57-git-revoir-ses-branches
content:
Suite à la lecture de l'article <a href="http://williamdurand.fr/2012/01/17/my-git-branching-model/">My Git Branching Model -- William DURAND</a>, je me suis rendu compte que c'était une peu brouillon de mon côté. Je trouve son modèle pratique.<br/>
<hr>
<h2>Le cas de Pombo</h2>
<br/>
J'ai donc voulu revoir le modèle de <a href="https://github.com/BoboTiG/pombo">Pombo</a>, entre autres. L'ancien modèle était le suivant&nbsp;: une seule branche <span style="font-style: italic;">master</span>, avec tout dedans à la <a href="http://byatoo.com/la-rache/">rache</a>.<br/>
La dernière version stable de Pombo est la 0.0.10, soit le commit n°<a href="https://github.com/BoboTiG/pombo/commit/35d769045ff866f1f2ed90df4009498311e83f47">31</a>. La version en cours de développement en est au commit n°<a href="https://github.com/BoboTiG/pombo/commit/6c8491a2a8baacd81efc38e50752f856a1948066">112</a>. Vous voyez le bousin arriver ?<br/>
<br/>
Coment faire ? La réponse est simple, la méthode aussi (enfin après quelques recherches)&nbsp;:<br/>
<ul>
<li>créer la branche <span style="font-style: italic;">develop</span></li>
<li>recréer la branche <span style="font-style: italic;">master</span> qui doit s'arrêter au commit n°31</li>
</ul>
En pratique, ça se fera tel que&nbsp;:<br/>
<pre><code class="language-bash"># créer la branche temporaire master-tmp à partir du commit n°31<br/>
git checkout 35d7690 -b master<br/>
<br/>
# renommer la branche master en develop<br/>
git branch -m master develop<br/>
<br/>
# renommer la branche master-tmp en master<br/>
git branch -m master-tmp master<br/>
<br/>
# pousser la branche develop<br/>
git push origin develop<br/>
# git config --global push.default simple<br/>
<br/>
# synchroniser la branche develop avec celle sur le serveur distant<br/>
git checkout develop<br/>
git push --set-upstream origin develop<br/>
<br/>
# supprimer la branche master distante, devenue obsolète<br/>
# si vous utilisez GitHub, pensez à déclarer la branche develop comme celle par défaut<br/>
git push origin&nbsp;:master<br/>
<br/>
# pousser la branche master nouvellement recréée<br/>
git push origin master<br/>
# si vous utilisez GitHub, pensez à remettre la branche master comme celle par défaut<br/>
<br/>
# synchroniser la branche master avec celle sur le serveur distant<br/>
git checkout master<br/>
git push --set-upstream origin master</code></pre>
Dans tout ça, la nouvelle commande pour moi est <span style="font-weight: bold;">git checkout &lt;id> -b &lt;nom></span>.<br/>
<br/>
<hr>
<h2>Nouvelle fonctionnalité</h2>
<br/>
Dorénavant, lors de l'ajout d'une fonctionnalité, j'ajouterai une nouvelle branche feat-&lt;nom> depuis <span style="font-style: italic;">develop</span>&nbsp;: <br/>
<pre><code class="language-bash">git checkout -b feat-&lt;nom> develop</code></pre>
<br/>
Mémo pour pousser une fonctionnalité dans la branche <span style="font-style: italic;">develop</span>&nbsp;:<br/>
<pre><code class="language-bash">git checkout develop<br/>
git pull --ff-only origin develop<br/>
git checkout feat-&lt;nom>
git merge feat-&lt;nom><br/>
git rebase develop<br/>
git merge --no-ff feat-&lt;nom><br/>
git push origin develop</code></pre>
<br/>
<hr>
Comme je compte appliquer ce modèle de branches à mes autres projets, voyez-vous une meilleure solution ?


feed_id: https://tiger-222.fr/index.php?mode=links&id=20131029235951
title: Routeurs déchus
uri: Routeurs-déchus
url: https://tiger-222.fr/?d=2013/10/29/23/59/51-routeurs-dechus
content:
<div style="text-align:center;"><img src="media/edec5404.WRT54Gv2.png" data-original-source="http://tiger-222.fr/img/WRT54Gv2.png" alt="Linksys WRT54G v2" /></div><br/>
En ce mois d'octobre, j'ai observé une recrudescence de portes dérobées (ou <span style="font-style: italic;">backdoors</span>) dans des routeurs grand public. Je vais tenter de regrouper des liens et donner un minimum d'explications, ça fera un petit guide de dépannage ☠<br/>
<br/>
Voici la liste des routeurs recensés&nbsp;:<br/>
<ul>
<li>D-Link DI-524UP</li>
<li>D-Link DI-604S,  DI-604UP, DI-604+</li>
<li>D-Link DI-624</li>
<li>D-Link DIR-100</li>
<li>D-Link DIR-120</li>
<li>D-Link DIR-815</li>
<li>D-Link TM-G5240</li>
<li>Medialink MWN-WAPR150N</li>
<li>Netgear WNDR3700v4</li>
<li>Netgear WNDR3800</li>
<li>Netgear WNDR4700</li>
<li>Planex BRL-04R, BRL-04UR, BRL-04CW</li>
<li>Tenda W302R</li>
<li>Tenda W330R</li></ul>
Aussi, il semblerait que certains modèle Netgear utilisent un mot de passe root <a href="https://code.google.com/p/netgear-telnetenable/">codé en dur</a>.<br/>
<br/>
<hr>
<h2>DLink DIR-815 UPnP Command Injection</h2>
<h6>Le 1<sup>er</sup> février 2013</h6>
<span style="color:gray;"><span style="text-decoration: underline;">Routeurs impactés</span>&nbsp;: D-Link DIR-815.</span><br/>
<br/>
<a href="http://shadow-file.blogspot.fr/2013/02/dlink-dir-815-upnp-command-injection.html">The Shadow File</a> avait 20 minutes à tuer. Et voilà que le D-Link tombe. En forgeant un packet tel que celui-ci&nbsp;:<br/>
<pre><code class="language-markup">M-SEARCH * HTTP/1.1<br/>
HOST:239.255.255.250:1900<br/>
ST:uuid:`reboot`  &lt;-- Ici, la commande désirée<br/>
MX:2<br/>
MAN:"ssdp:discover"</code></pre>
Qu'il faut envoyer en <a href="https://fr.wikipedia.org/wiki/Multicast">multicast</a> à l'addresse IP 239.255.255.250 sur le port UDP (1900). Il y a même un <a href="https://github.com/zcutlip/exploit-poc/tree/master/dlink/dir-815-a1/upnp-command-injection">script python</a> qui permet d'automatiser la tâche et spécifier une commande.<br/>
<br/>
<hr>
<h2>Reverse Engineering a D-Link Backdoor</h2>
<h6>Le 12 octobre 2013</h6>
<span style="color:gray;"><span style="text-decoration: underline;">Routeurs impactés</span>&nbsp;: D-Link DI-524UP, D-Link DI-604S, D-Link DI-604UP, D-Link DI-604+, D-Link DI-624, D-Link DIR-100, D-Link DIR-120, D-Link TM-G5240, Planex BRL-04R, Planex BRL-04UR et Planex BRL-04CW.</span><br/>
<br/>
Un chercheur en sécurité de chez <a href="http://www.devttys0.com/2013/10/reverse-engineering-a-d-link-backdoor/">/dev/ttyS0</a> à découvert qu'un certain Joel à implémenté une porte dérobée dans les routeurs utilisant le <a href="https://tiger-222.fr/ftp://ftp.dlink.eu/Products/dir/dir-100/driver_software/DIR-100_fw_reva_113_ALL_en_20110915.zip">firmware v1.13</a>. L'exploit est on ne peut plus simple&nbsp;: il suffit de modifier l'<a href="https://fr.wikipedia.org/wiki/User-Agent">User-Agent</a> tel que&nbsp;:<br/>
<pre><code class="language-markup">xmlset_roodkcableoj28840ybtide</code></pre>
Pour le côté fun, si on lit à l'envers, ça donne «&nbsp;Edit by 04882 Joel Backdoor&nbsp;». Merci Joel.<br/>
<br/>
<hr>
<h2>From China, With Love</h2>
<h6>Le 17 octobre 2013</h6>
<span style="color:gray;"><span style="text-decoration: underline;">Routeurs impactés</span>&nbsp;: Tenda W302R, Tenda W330R ou encore Medialink MWN-WAPR150N.</span><br/>
<br/>
Toujours un chercheur en sécurité de chez <a href="http://www.devttys0.com/2013/10/from-china-with-love/">/dev/ttyS0</a>, tout se passe au niveau de la forge du packet&nbsp;:<br/>
<pre><code class="language-markup">echo -ne "w302r_mfg\x00x/bin/ls" | nc -u -q 5 IP_routeur 7329</code></pre>
Notez le "/bin/ls" dans le "echo", c'est la commande qui sera exécutée en root...<br/>
<br/>
<hr>
<h2>Complete, Persistent Compromise of Netgear Wireless Routers </h2>
<h6>Le 22 octobre 2013</h6>
<span style="color:gray;"><span style="text-decoration: underline;">Routeurs impactés</span>&nbsp;: Netgear WNDR3700v4, Netgear WNDR3800 et Netgear WNDR4700.</span><br/>
<br/>
<a href="http://shadow-file.blogspot.fr/2013/10/complete-persistent-compromise-of.html">The Shadow File</a> a mis à mal les routeurs Netgear, bien comme il faut...<br/>
Il suffit de se rendre à l'adresse suivante pour désactiver <span style="font-weight: bold;">totalement</span> le contrôle d'accès&nbsp;:<br/>
<pre><code class="language-markup"><a href="http://IP_routeur/BRS_02_genieHelp.html">http://IP_routeur/BRS_02_genieHelp.html</a></code></pre>
<br/>
Pour voir les mots de passe Wi-Fi <span style="font-weight: bold;">en clair</span>&nbsp;:<br/>
<pre><code class="language-markup"><a href="http://IP_routeur/BRS_success.html">http://IP_routeur/BRS_success.html</a></code></pre>
<br/>
Et puis on peut aussi <a href="http://shadow-file.blogspot.fr/2013/10/netgear-root-compromise-via-command.html">passer des commandes shell</a>, sinon c'est pas rigolo. J'en garde une <a href="https://tiger-222.fr/paste/?3ec20a62650c94a5#m8h84Z277Ajt/NqYpt1ZeEbGiHwOvzvSGv78v39pjCw">copie</a>, juste au cas où.<br/>
<br/>
<hr>
<h2>Bref&nbsp;!</h2>
<br/>
Comme disait Pépin.<br/>
J'ai bien peur que d'autres soient à venir... En attendant, quelques lecture intéressantes&nbsp;:<br/>
<ul>
<li><a href="http://shahart.al/2013/10/16/alice-in-router-land-down-the-mp-202-hole/">Alice in Router-land: Down The MP-202 Hole</a> qui s'occupe de l'AudioCodes MP-202</li></ul>
Et sinon, vive le libre, vive le <a href="http://support.linksys.com/fr-eu/support/routers/WRT54G">Linksys WRT54G</a> (photo de l'article) et son firmware open-source <a href="http://www.dd-wrt.com/">DD-WRT</a>&nbsp;!


feed_id: https://tiger-222.fr/index.php?mode=links&id=20131031000157
title: Python : mémoisation
uri: Python-mémoisation
url: https://tiger-222.fr/?d=2013/10/31/00/01/57-python-memoisation
content:
<div style="text-align:center;"><img src="media/ef307b82.memoisation-elephant.jpg" data-original-source="http://tiger-222.fr/img/memoisation-elephant.jpg" alt="Œuvre d'Anthony Heywood" /><br/>
<span style="color:gray;">Connaissez le dicton&nbsp;: avoir une mémoire d'...</span></div><br/>
La <a href="http://fr.wikipedia.org/wiki/M%C3%A9moization">mémoisation</a> est une technique d'optimisation de code consistant à réduire le temps d'exécution d'une fonction en mémorisant ses résultats d'une fois sur l'autre, une sorte de cache quoi. Ça peut-être super pratique dans certains cas, surtout lorsqu'il y a des calculs complexes ou beaucoup de données redondantes.<br/>
Étant donné que <a href="http://sametmax.com/memoization-dune-fonction-python/">Sam & Max</a> ont déjà couvert le sujet, je vais seulement montrer un exemple concrêt&nbsp;: le cas de mon module <a href="https://tiger-222.fr/?tag=MSS">MSS</a>.<br/>
<hr>
<h2>Le contexte</h2>
<br/>
Le module MSS est, comme sont nom ne l'indique pas, un module permettant de prendre des captures d'écran sans module tiers, seulement du python pur. J'utilise intensément le module ctypes, qui permet d'appeler des fonctions C/C++ depuis python.<br/>
Sous GNU/Linux, avec un code équivalent C <=> python permettant de prendre une capture d'écran, la différence de vitesse d'exécution est quintuplée, voire sextuplée. Ça fait beaucoup. Je me suis donc plongé dans le code pour voir ce qui pouvait être revu ou amélioré. Au final, il s'avère que les routines pour récupérer les pixels et générer l'image PNG seront améliorées. Mais le gain fût minime.<br/>
Le stockage des pixels reçus par la fonction <a href="http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/ImUtil.c#n444">XGetPixel</a> met un temps fou, c'est un gouffre. C'est là qu'il faut farfouiller, voilà le code fautif&nbsp;:<br/>
<pre><code class="language-python">def pix(pixel):<br/>
    ''' Apply shifts to a pixel to get the RGB values. '''<br/>
    return b((pixel ET 16711680) >> 16) + b((pixel ET 65280) >> 8) + b(pixel ET 255)<br/>
<br/>
get_pix = self.XGetPixel<br/>
pixels = [pix(get_pix(image, x, y)) for y in range(height) for x in range(width)]</code></pre>
<div style="text-align:right;"><span style="color:gray;">La coloration syntaxique chie dans la colle, remplacez le <span style="font-style: italic;">ET</span> par <span style="font-style: italic;">&</span>.</span></div><br/>
Dans la fonction <span style="font-style: italic;">pix()</span>, le décalage de bits n'est pas le plus gourmant, ce sont les concaténations. En effet, à chaque fois, il y a réallocation de mémoire et copie de données dont je me passerais bien.<br/>
<br/>
<hr>
<h2>Mémoisation</h2>
<br/>
Dans la logique qui m'habite (rien de bien transcendant...), je me dis qu'il y a énormément de pixels identiques sur un écran. Il y a la dose même. Avec une telle quantitié de données, et sachant les opérations qu'il faille faire sur chacun des pixels, la mémoisation prend tout son sens&nbsp;:<br/>
<pre><code class="language-python">def pix(px, _resultats={}):<br/>
    # Apply shifts to a pixel to get the RGB values.<br/>
    # This method uses of memoization.<br/>
    if not px in _resultats:<br/>
        _resultats[px] = b((px ET 16711680) >> 16) + b((px ET 65280) >> 8) + b(px ET 255)<br/>
    return _resultats[px]<br/>
<br/>
get_pix = self.XGetPixel<br/>
pixels = [pix(get_pix(image, x, y)) for y in range(height) for x in range(width)]</code></pre>
<div style="text-align:right;"><span style="color:gray;">J'ai modifié <span style="font-style: italic;">pixel</span> par <span style="font-style: italic;">px</span> afin d'éviter les barres de défilement...</span></div><br/>
Étant donné que les paramètres sont initialisés à la déclaration, le paramètre <span style="font-style: italic;">_resultats</span>  de la fonction <span style="font-style: italic;">pix()</span> ne sera pas recréé à chaque appel. Il s'agit d'un <span style="font-style: italic;">dict</span> qui recevra tous les pixels et le résultat attendu pour chacun d'eux. Dans ladite fonction, on vérifie si le pixel a déja été traité, si non, on effectue les opérations sur celui-ci, puis on renvoie ce que le <span style="font-style: italic;">dict</span> a en mémoire. Un petit cache tout simple et efficace.<br/>
<br/>
<hr>
<h2>Résultats</h2>
<br/>
Avec un écran de <span style="font-style: italic;">1280x1024</span>, je passe de <span style="font-weight: bold;">±4</span> sec à <span style="font-weight: bold;">&lt;2</span> sec, reduisant les pixels traités de <code class="language-python">1 310 720</code> à <code class="language-python">11 204</code>.<br/>
Avec un écran de <span style="font-style: italic;">1920x1280</span>, je passe de <span style="font-weight: bold;">±6</span> sec à <span style="font-weight: bold;">&lt;3</span> sec, reduisant les pixels traités de <code class="language-python">2 457 600</code> à <code class="language-python">8 236</code>.<br/>
<br/>
♪ Un <a href="https://www.youtube.com/watch?v=Fe_tH-SKGYQ">gain</a> non négligeable&nbsp;! ♪


feed_id: https://tiger-222.fr/index.php?mode=links&id=20131106233535
title: Code : fautes d'orthographe courantes
uri: Code-fautes-d-orthographe-courantes
url: https://tiger-222.fr/?d=2013/11/06/23/35/35-code-fautes-dorthographe-courantes
content:
<a href="https://github.com/lucasdemarchi/codespell">Codespell</a>, de <a href="http://www.politreco.com">Lucas De Marchi</a>, est un de ces petits utilitaires qui ne paie pas de mine, mais ô combien pratique&nbsp;! Il vérifie les fautes d'orthographe courantes dans le code et les fichiers en relation (genre un README ou un CHANGELOG). Il n'a rien d'extraordinaire en soi, mais il permet de faire les choses correctement.<br/>
<div style="text-align:center;"><img src="media/27faf0b6.codespell.png" data-original-source="http://tiger-222.fr/img/codespell.png" alt="codespell" /></div><br/>
Dans les exemples ci-dessus, vous pouvez voir que j'ai merdé à trois reprises dans le module <a href="https://tiger-222.fr/?tag=mss">MSS</a>... Mais aussi qu'il y a des erreurs dans le code officiel de Python 2.7.5 (personne n'est parfait)&nbsp;! <span style="font-style: italic;">D'ailleurs, pour ceux et celles qui souhaitent participer à un projet open-source, c'est un excellent moyen pour se mettre dans le bain&nbsp;: proposer des patches qui corrigent les fautes d'orthographe.</span> 😉<br/>
<br/>
<hr>
<h2>Les options</h2>
<br/>
Si les couleurs vous dérangent, passez l'option  <code class="language-markup">--disable-colors</code>. Et si les statistiques vous bottent, l'option  <code class="language-markup">--summary</code> permet de savoir combien de corrections ont été appliquées.<br/>
<br/>
Pour ne pas faire de recherches dans certains fichiers, utiisez l'option <code class="language-markup">-S SKIP</code>, dont les valeurs sont séparées par une virgule&nbsp;:<br/>
<pre><code class="language-bash">$ codespell -S .pyc,.txt<br/>
<br/>
# Avec joker<br/>
$ codespell -S "*.pyc,.git,*backup*"</code></pre>
<br/>
Bien évidemment, il est possible d'utiliser son propre dictionnaire à l'aide de l'option <code class="language-markup">-D FICHIER</code>, dont chaque ligne devra être telle que&nbsp;:<br/>
<pre><code class="language-bash"># mot_erroné-&gt;mot_correct<br/>
aberation-&gt;aberration<br/>
<br/>
# mot_erroné-&gt;mot_correct, autre_mot_possible,<br/>
coorperation-&gt;cooperation, corporation,<br/>
<br/>
# mot_erroné-&gt;mot_correct, explication<br/>
# Ceci aura pour effet de ne pas appliquer automatiquement les changements.<br/>
# Pratique pour les mots à double sens, réservés ou à tendance "faux positif".<br/>
cmo-&gt;com, disabled due to lots of false positives</code></pre>
<br/>
Il existe même un mode intéractif&nbsp;! C'est l'option <code class="language-markup">-I VALEUR</code> qui s'en charge. Elle n'est utilisable qu'avec l'option <code class="language-markup">--write-changes</code>, qui applique directement les changements sur les fichiers. Les valeurs possibles sont&nbsp;:<br/>
<pre><code class="language-bash">0&nbsp;: aucune intéractivité, le comportement par défaut<br/>
1&nbsp;: demander une confirmation avant chaque modification<br/>
2&nbsp;: permet de choisir un mot parmis la liste, si choix il y a<br/>
3&nbsp;: options 1 et 2</code></pre>
<br/>
Enfin, pour gérer facilement les messages en sortie, l'option  <code class="language-markup">-q NIVEAU</code> permet d'affiner tout ça&nbsp;:<br/>
<pre><code class="language-markup"> 0&nbsp;: tout est affiché, valeur par défaut<br/>
 1&nbsp;: pas d'averto en cas d'erreur d'encodage<br/>
 2&nbsp;: pas d'averto pour les fichiers binaires<br/>
 4&nbsp;: pas d'averto lors de non modification (explication dans le dictionnaire)<br/>
 8&nbsp;: ne rien afficher en mode non-automatique<br/>
16&nbsp;: ne pas afficher les fichiers corrigés</code></pre>
<br/>
<span style="font-weight: bold;">Bonus</span>&nbsp;: un alias qui va bien pour votre .bashrc (ou mieux, .zshrc)&nbsp;:<br/>
<pre><code class="language-bash">alias codespell='/opt/codespell/codespell.py'</code></pre>
<br/>
<hr>
<h2>3615 ma vie</h2>
<br/>
Pour la petite histoire, j'ai découvert cet outil grâce à la dépêche <a href="http://linuxfr.org/news/sortie-de-linux-3-12">Noyau&nbsp;: Sortie de Linux 3.12</a> sur LinuxFr.org. De fil en aiguille, j'en suis arrivé à décortiquer un <a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=ae67d9a888a000a9df43de10eb9950075e93508c">pull-request de Ted Ts'o</a> dans lequel j'ai pu lire&nbsp;:<br/>
<pre><code class="language-markup">ext4: Fix misspellings using 'codespell' tool</code></pre>
<br/>
Du coup, je vous le donne en mille&nbsp;: le <a href="https://github.com/BoboTiG/python-mss/commit/2ecfc45ef6d55c3b34b1b14608c47260ce76a777">commit pour MSS</a>, super original...


feed_id: https://tiger-222.fr/index.php?mode=links&id=20131108131926
title: Se protéger contre soi-même !
uri: Se-protéger-contre-soi-même
url: https://tiger-222.fr/?d=2013/11/08/13/19/26-se-proteger-contre-soi-meme
content:
Un accès au compte root, la commande rm disponible... Un mélange détonnant qui peut faire très mal. Ça sent l'erreur de manipulation de débutant tout ça&nbsp;!<br/>
<br/>
À fond dans mon nouveau projet, dont je vous parlerai plus tard, je dois supprimer les fichiers d'un répertoire. Si elle n'est pas belle celle-ci&nbsp;:<br/>
 <div style="text-align:center;"><img src="media/890fb75b.outch-root-rm.png" data-original-source="http://tiger-222.fr/img/outch-root-rm.png" alt="Misère avec la commande rm" /></div><br/>
Putain&nbsp;!  Encore heureux que je n'avais pas utilisé l'argument <code class="language-bash">-r ou --recursive</code> ☠<br/>
<br/>
L'erreur à la con, ici, c'est que j'ai utilisé la touche TAB pour que Zsh complète le nom des chemins automatiquement. Vite fait, bien fait, ça aurait pu m'être fatal&nbsp;!<br/>
<br/>
<span style="font-weight: bold;">La synthèse de cette histoire</span>&nbsp;: toujours faire attention.<br/>
<span style="font-weight: bold;">La morale de cette histoire</span>&nbsp;: toujours faire <span style="font-style: italic;">très</span> attention.<br/>
<span style="font-weight: bold;"><span style="text-decoration: underline;">La morale de cette morale</span></span>&nbsp;: toujours faire <span style="font-style: italic;">super</span> attention. TOUJOURS&nbsp;!<br/>
<br/>
Et afin de me protéger (contre moi-même), un alias qui va bien&nbsp;:<br/>
<pre><code class="language-bash">alias rm='rm -Iv'</code></pre>
L'argument <code class="language-bash">-I</code> est le mode intéractif. J'te jure, des fois... $#!°@☣


feed_id: https://tiger-222.fr/?mode=links&id=20131108131926
title: Se protéger contre soi-même !
uri: 2013-11-19-Se-protéger-contre-soi-même
url: https://tiger-222.fr/?d=2013/11/08/13/19/26-se-proteger-contre-soi-meme
content:
Un accès au compte root, la commande rm disponible... Un mélange détonnant qui peut faire très mal. Ça sent l'erreur de manipulation de débutant tout ça&nbsp;!<br/>
<br/>
À fond dans mon nouveau projet, dont je vous parlerai plus tard, je dois supprimer les fichiers d'un répertoire. Si elle n'est pas belle celle-ci&nbsp;:<br/>
 <div style="text-align:center;"><img src="media/890fb75b.outch-root-rm.png" data-original-source="http://tiger-222.fr/img/outch-root-rm.png" alt="Misère avec la commande rm" /></div><br/>
Putain&nbsp;!  Encore heureux que je n'avais pas utilisé l'argument <code class="language-bash">-r ou --recursive</code> ☠<br/>
<br/>
L'erreur à la con, ici, c'est que j'ai utilisé la touche TAB pour que Zsh complète le nom des chemins automatiquement. Vite fait, bien fait, ça aurait pu m'être fatal&nbsp;!<br/>
<br/>
<span style="font-weight: bold;">La synthèse de cette histoire</span>&nbsp;: toujours faire attention.<br/>
<span style="font-weight: bold;">La morale de cette histoire</span>&nbsp;: toujours faire <span style="font-style: italic;">très</span> attention.<br/>
<span style="font-weight: bold;"><span style="text-decoration: underline;">La morale de cette morale</span></span>&nbsp;: toujours faire <span style="font-style: italic;">super</span> attention. TOUJOURS&nbsp;!<br/>
<br/>
Et afin de me protéger (contre moi-même), un alias qui va bien&nbsp;:<br/>
<pre><code class="language-bash">alias rm='rm -Iv'</code></pre>
L'argument <code class="language-bash">-I</code> est le mode intéractif. J'te jure, des fois... $#!°@☣<br/>
<br/>
<span style="font-weight: bold;">MàJ</span>&nbsp;: <a href="https://tiger-222.fr/index.php?d=2013/11/08/13/19/26-#id2ac124">ArthurHoaro</a> propose une solution moins chiante ☺


feed_id: https://tiger-222.fr/?mode=links&id=20131029235951
title: Routeurs déchus
uri: 2013-11-19-Routeurs-déchus
url: https://tiger-222.fr/?d=2013/10/29/23/59/51-routeurs-dechus
content:
<div style="text-align:center;"><img src="media/edec5404.WRT54Gv2.png" data-original-source="http://tiger-222.fr/img/WRT54Gv2.png" alt="Linksys WRT54G v2" /></div><br/>
En ce mois d'octobre, j'ai observé une recrudescence de portes dérobées (ou <span style="font-style: italic;">backdoors</span>) dans des routeurs grand public. Je vais tenter de regrouper des liens et donner un minimum d'explications, ça fera un petit guide de dépannage ☠<br/>
<br/>
Voici la liste des routeurs recensés&nbsp;:<br/>
<ul>
<li>D-Link DI-524UP</li>
<li>D-Link DI-604S,  DI-604UP, DI-604+</li>
<li>D-Link DI-624</li>
<li>D-Link DIR-100</li>
<li>D-Link DIR-120</li>
<li>D-Link DIR-815</li>
<li>D-Link TM-G5240</li>
<li>Medialink MWN-WAPR150N</li>
<li>Netgear WNDR3700v4</li>
<li>Netgear WNDR3800</li>
<li>Netgear WNDR4700</li>
<li>Planex BRL-04R, BRL-04UR, BRL-04CW</li>
<li>Tenda W302R</li>
<li>Tenda W330R</li></ul>
<span style="font-weight: bold;">Voir la partie des <a href="https://tiger-222.fr/#lectures">lectures intéressantes</a>, il y a d'autres routeurs concernés.</span><br/>
Aussi, il semblerait que certains modèle Netgear utilisent un mot de passe root <a href="https://code.google.com/p/netgear-telnetenable/">codé en dur</a>.<br/>
<br/>
<hr>
<h2>DLink DIR-815 UPnP Command Injection</h2>
<h6>Le 1<sup>er</sup> février 2013</h6>
<span style="color:gray;"><span style="text-decoration: underline;">Routeurs impactés</span>&nbsp;: D-Link DIR-815.</span><br/>
<br/>
<a href="http://shadow-file.blogspot.fr/2013/02/dlink-dir-815-upnp-command-injection.html">The Shadow File</a> avait 20 minutes à tuer. Et voilà que le D-Link tombe. En forgeant un packet tel que celui-ci&nbsp;:<br/>
<pre><code class="language-markup">M-SEARCH * HTTP/1.1<br/>
HOST:239.255.255.250:1900<br/>
ST:uuid:`reboot`  &lt;-- Ici, la commande désirée<br/>
MX:2<br/>
MAN:"ssdp:discover"</code></pre>
Qu'il faut envoyer en <a href="https://fr.wikipedia.org/wiki/Multicast">multicast</a> à l'addresse IP 239.255.255.250 sur le port UDP (1900). Il y a même un <a href="https://github.com/zcutlip/exploit-poc/tree/master/dlink/dir-815-a1/upnp-command-injection">script python</a> qui permet d'automatiser la tâche et spécifier une commande.<br/>
<br/>
<hr>
<h2>Reverse Engineering a D-Link Backdoor</h2>
<h6>Le 12 octobre 2013</h6>
<span style="color:gray;"><span style="text-decoration: underline;">Routeurs impactés</span>&nbsp;: D-Link DI-524UP, D-Link DI-604S, D-Link DI-604UP, D-Link DI-604+, D-Link DI-624, D-Link DIR-100, D-Link DIR-120, D-Link TM-G5240, Planex BRL-04R, Planex BRL-04UR et Planex BRL-04CW.</span><br/>
<br/>
Un chercheur en sécurité de chez <a href="http://www.devttys0.com/2013/10/reverse-engineering-a-d-link-backdoor/">/dev/ttyS0</a> à découvert qu'un certain Joel à implémenté une porte dérobée dans les routeurs utilisant le <a href="https://tiger-222.fr/ftp://ftp.dlink.eu/Products/dir/dir-100/driver_software/DIR-100_fw_reva_113_ALL_en_20110915.zip">firmware v1.13</a>. L'exploit est on ne peut plus simple&nbsp;: il suffit de modifier l'<a href="https://fr.wikipedia.org/wiki/User-Agent">User-Agent</a> tel que&nbsp;:<br/>
<pre><code class="language-markup">xmlset_roodkcableoj28840ybtide</code></pre>
Pour le côté fun, si on lit à l'envers, ça donne «&nbsp;Edit by 04882 Joel Backdoor&nbsp;». Merci Joel.<br/>
<br/>
<hr>
<h2>From China, With Love</h2>
<h6>Le 17 octobre 2013</h6>
<span style="color:gray;"><span style="text-decoration: underline;">Routeurs impactés</span>&nbsp;: Tenda W302R, Tenda W330R ou encore Medialink MWN-WAPR150N.</span><br/>
<br/>
Toujours un chercheur en sécurité de chez <a href="http://www.devttys0.com/2013/10/from-china-with-love/">/dev/ttyS0</a>, tout se passe au niveau de la forge du packet&nbsp;:<br/>
<pre><code class="language-markup">echo -ne "w302r_mfg\x00x/bin/ls" | nc -u -q 5 IP_routeur 7329</code></pre>
Notez le "/bin/ls" dans le "echo", c'est la commande qui sera exécutée en root...<br/>
<br/>
<hr>
<h2>Complete, Persistent Compromise of Netgear Wireless Routers </h2>
<h6>Le 22 octobre 2013</h6>
<span style="color:gray;"><span style="text-decoration: underline;">Routeurs impactés</span>&nbsp;: Netgear WNDR3700v4, Netgear WNDR3800 et Netgear WNDR4700.</span><br/>
<br/>
<a href="http://shadow-file.blogspot.fr/2013/10/complete-persistent-compromise-of.html">The Shadow File</a> a mis à mal les routeurs Netgear, bien comme il faut...<br/>
Il suffit de se rendre à l'adresse suivante pour désactiver <span style="font-weight: bold;">totalement</span> le contrôle d'accès&nbsp;:<br/>
<pre><code class="language-markup"><a href="http://IP_routeur/BRS_02_genieHelp.html">http://IP_routeur/BRS_02_genieHelp.html</a></code></pre>
<br/>
Pour voir les mots de passe Wi-Fi <span style="font-weight: bold;">en clair</span>&nbsp;:<br/>
<pre><code class="language-markup"><a href="http://IP_routeur/BRS_success.html">http://IP_routeur/BRS_success.html</a></code></pre>
<br/>
Et puis on peut aussi <a href="http://shadow-file.blogspot.fr/2013/10/netgear-root-compromise-via-command.html">passer des commandes shell</a>, sinon c'est pas rigolo. J'en garde une <a href="https://tiger-222.fr/paste/?3ec20a62650c94a5#m8h84Z277Ajt/NqYpt1ZeEbGiHwOvzvSGv78v39pjCw">copie</a>, juste au cas où.<br/>
<br/>
<hr>
<h2 id="lectures">Bref&nbsp;!</h2>
<br/>
Comme disait Pépin. J'ai bien peur que d'autres soient à venir...<br/>
<br/>
En attendant, quelques lecture intéressantes&nbsp;:<br/>
<ul>
<li> <a href="http://shahart.al/2013/10/16/alice-in-router-land-down-the-mp-202-hole/">Alice in Router-land: Down The MP-202 Hole</a> qui s'occupe de l'AudioCodes MP-202</li>
<li> D-Link DSR-150 & DSR-150N, DSR-250 & DSR-250N, DSR-500 & DSR-500N et DSR-1000 &DSR-1000N&nbsp;: <a href="http://www.exploit-db.com/exploits/30062/">D-Link DSR Router Series - Remote Root Shell Exploit</a> -- <a href="https://tiger-222.fr/paste/?7ecea743e10c14be#9Al+uAR5+mqrHq1S3DppWzIS4hNaVULlAm2EotLHgDM=">copie</a></li>
<li> <a href="http://www.exploit-db.com/exploits/30362/">Cisco EPC3925 - Cross Site Request Forgery</a> -- <a href="https://tiger-222.fr/paste/?912177b10349d236#8sbcOrHpMtwJyx/fFQrkJgs4pMHWwZCKmmDhvTw2HpU=">copie</a></li>
<li> <a href="http://www.exploit-db.com/exploits/29919/">TP-Link TL-WR740N / TL-WR740ND - 150M Wireless Lite N Router HTTP DoS</a> -- <a href="https://tiger-222.fr/paste/?8c1e41378b7e8d6a#etS1tFogxr360/9pEluEVOAuFr1Ptuk09DQIBN5c9q8=">copie</a></li>
<li> <a href="http://www.exploit-db.com/exploits/30665/">Nisuta NS-WIR150NE, NS-WIR300N Wireless Routers Remote Management Web Interface Authentication Bypass Vulnerability</a> -- <a href="https://tiger-222.fr/paste/?d0fe5ca68a67b68b#m+DO5Gs0TqcyJ/44sX3woHc4570FDBuXEW4maWBxd+s=">copie</a></li>
<li> <a href="http://www.exploit-db.com/exploits/30547/">D-Link DSL-2750U ME_1.09 - CSRF Vulnerability</a> -- <a href="https://tiger-222.fr/paste/?e6d74e45e6793ffd#uZFR0jBjMjWUJjUBvWENTFx9MZP1le1zU/xDbO22keQ=">copie</a></li></ul>
Et sinon, vive le libre, vive le <a href="http://support.linksys.com/fr-eu/support/routers/WRT54G">Linksys WRT54G</a> (photo de l'article) et son firmware open-source <a href="http://www.dd-wrt.com/">DD-WRT</a>&nbsp;!


feed_id: https://tiger-222.fr/?mode=links&id=20131029122357
title: Git : revoir ses branches
uri: 2013-11-19-Git-revoir-ses-branches
url: https://tiger-222.fr/?d=2013/10/29/12/23/57-git-revoir-ses-branches
content:
Suite à la lecture de l'article <a href="http://williamdurand.fr/2012/01/17/my-git-branching-model/">My Git Branching Model -- William DURAND</a>, je me suis rendu compte que c'était une peu brouillon de mon côté. Je trouve son modèle pratique.<br/>
<hr>
<h2>Le cas de Pombo</h2>
<br/>
J'ai donc voulu revoir le modèle de <a href="https://github.com/BoboTiG/pombo">Pombo</a>, entre autres. L'ancien modèle était le suivant&nbsp;: une seule branche <span style="font-style: italic;">master</span>, avec tout dedans à la <a href="http://byatoo.com/la-rache/">rache</a>.<br/>
La dernière version stable de Pombo est la 0.0.10, soit le commit n°<a href="https://github.com/BoboTiG/pombo/commit/35d769045ff866f1f2ed90df4009498311e83f47">31</a>. La version en cours de développement en est au commit n°<a href="https://github.com/BoboTiG/pombo/commit/6c8491a2a8baacd81efc38e50752f856a1948066">112</a>. Vous voyez le bousin arriver ?<br/>
<br/>
Coment faire ? La réponse est simple, la méthode aussi (enfin après quelques recherches)&nbsp;:<br/>
<ul>
<li>créer la branche <span style="font-style: italic;">develop</span></li>
<li>recréer la branche <span style="font-style: italic;">master</span> qui doit s'arrêter au commit n°31</li>
</ul>
En pratique, ça se fera tel que&nbsp;:<br/>
<pre><code class="language-bash"># créer la branche temporaire master-tmp à partir du commit n°31<br/>
git checkout 35d7690 -b master-tmp<br/>
<br/>
# renommer la branche master en develop<br/>
git branch -m master develop<br/>
<br/>
# renommer la branche master-tmp en master<br/>
git branch -m master-tmp master<br/>
<br/>
# pousser la branche develop<br/>
git push origin develop<br/>
# git config --global push.default simple<br/>
<br/>
# synchroniser la branche develop avec celle sur le serveur distant<br/>
git checkout develop<br/>
git push --set-upstream origin develop<br/>
<br/>
# supprimer la branche master distante, devenue obsolète<br/>
# si vous utilisez GitHub, pensez à déclarer la branche develop comme celle par défaut<br/>
git push origin&nbsp;:master<br/>
<br/>
# pousser la branche master nouvellement recréée<br/>
git push origin master<br/>
# si vous utilisez GitHub, pensez à remettre la branche master comme celle par défaut<br/>
<br/>
# synchroniser la branche master avec celle sur le serveur distant<br/>
git checkout master<br/>
git push --set-upstream origin master</code></pre>
Dans tout ça, la nouvelle commande pour moi est <span style="font-weight: bold;">git checkout &lt;id> -b &lt;nom></span>.<br/>
<br/>
<hr>
<h2>Nouvelle fonctionnalité</h2>
<br/>
Dorénavant, lors de l'ajout d'une fonctionnalité, j'ajouterai une nouvelle branche feat-&lt;nom> depuis <span style="font-style: italic;">develop</span>&nbsp;: <br/>
<pre><code class="language-bash">git checkout -b feat-&lt;nom> develop</code></pre>
<br/>
Mémo pour pousser une fonctionnalité dans la branche <span style="font-style: italic;">develop</span>&nbsp;:<br/>
<pre><code class="language-bash">git checkout develop<br/>
git pull --ff-only origin develop<br/>
git checkout feat-&lt;nom>
git merge feat-&lt;nom><br/>
git rebase develop<br/>
git merge --no-ff feat-&lt;nom><br/>
git push origin develop</code></pre>
<br/>
<hr>
Comme je compte appliquer ce modèle de branches à mes autres projets, voyez-vous une meilleure solution ?


feed_id: https://tiger-222.fr/?mode=links&id=20130624155707
title: Vie privée : les fuites
uri: 2013-11-19-Vie-privée-les-fuites
url: https://tiger-222.fr/?d=2013/06/24/15/57/07-vie-privee-les-fuites
content:
<h2>Pourquoi cet article ?</h2>
<br/>
Pour avoir un recueil de documents qui serviront à prouver que la vie privée sur le web, et bien... Ce n'est pas vraiment ça&nbsp;!<br/>
À force de rechercher des preuves pour mes interlocuteurs/interlocutrices lorsque je parle des grandes firmes comme Apple, Google ou Facebook, je me suis dit qu'un article à jour serait intéressant.<br/>
Le voici donc&nbsp;! Couplé aux autres informations portant sur la <a href="https://tiger-222.fr/index.php?d=2013/04/05/16/16/53-telecommunications-et-securite">sécurité des télécommunications</a>, il y a de quoi faire réagir.<br/>
<br/>
Pour ceux et celles qui pensent qu'ils/elles n'ont rien à cacher, visionnez les quelques <a href="https://tiger-222.fr/#videos">vidéos en bas de page</a>.<br/>
Pour agir => <a href="http://www.controle-tes-donnees.net/">Reprenez le contrôle de vos données&nbsp;!</a>, <a href="http://prism-break.org/">PRISM Break</a>.<br/>
<br/>
<hr/>
<h3 id="etat-francais">État français</h3>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[8] [9] [10]</span></li>
<li>2013-05-07&nbsp;: <a href="http://lexpansion.lexpress.fr/high-tech/internet-sms-comment-thales-va-mettre-les-reseaux-francais-sur-ecoute_383757.html">Internet, SMS&nbsp;: comment Thales va mettre les réseaux français sur écoute</a></li>
<li>2013-07-04&nbsp;: <a href="http://korben.info/infrastructure-de-mutualisation.html">Infrastructure de mutualisation</a></li></ul>
<br/>
<h3 id="apple">Apple</h3>
<span style="font-style: italic;">Liste des services, logiciels et matériels faussement transparents&nbsp;:</span> iMessage, iPad, iPhone, iPod, iTunes, SIRI<br/>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[1]</span></li>
<li>2011-04-20&nbsp;: <a href="http://reflets.info/avec-apple-nous-sommes-bien-pris-en-mains-trop/">Avec Apple, nous sommes bien pris en mains… Trop ?</a></li>
<li>2011-10-20&nbsp;: <a href="http://reflets.info/siri-apple-se-lance-t-il-dans-le-fichage-biometrique-de-masse/">SIRI&nbsp;: Apple se lance t-il dans le fichage biométrique de masse ?</a></li>
<li>2012-09-05&nbsp;: <a href="http://rt.com/news/apple-patent-transmission-block-408/">No shooting at protest? Police may block mobile devices via Apple</a></li>
<li>2013-10-19&nbsp;: <a href="http://www.developpez.com/actu/62821/iMessage-Apple-pourrait-lire-vos-messages-le-chiffrement-de-son-application-mis-en-cause-par-deux-chercheurs/">iMessage&nbsp;: Apple pourrait lire vos messages</a></li>
<li>2013-10-21&nbsp;: <a href="http://korben.info/imessages-hack-video.html">Démo vidéo d’une interception sur iMessages</a></li></ul>
<br/>
<h3 id="facebook">Facebook</h3>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[2] [4] [5] [8] [9]</span></li>
<li>2013-06-13&nbsp;: <a href="http://www.nikopik.com/2013/06/facebook-communique-tous-vos-messages-censes-etre-prives.html">Facebook communique tous vos messages censés être privés</a></li>
<li>2013-06-13&nbsp;: <a href="http://www.nikopik.com/2013/03/facebook-laisse-vos-photos-accessibles-a-tous-depuis-des-annees-et-ca-ne-risque-pas-de-changer.html">Facebook laisse vos photos accessibles à tous depuis des années... et ça ne risque pas de changer</a></li>
<li>2013-06-20&nbsp;: <a href="http://www.theatlanticwire.com/technology/2013/06/facebooks-former-security-chief-now-works-nsa/66432/">Facebook's Former Security Chief Now Works for the NSA </a></li>
<li>2013-09-30&nbsp;: <a href="http://pro.clubic.com/blog-forum-reseaux-sociaux/facebook/actualite-588844-twitter-facebook-partage-donnees-chaines-television.html">Facebook partage ses données avec les chaînes de télévision</a></li></ul>
<br/>
<h3 id="fbi">FBI</h3>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[2] [3] [7]</span></li>
<li>2013-06-05&nbsp;: <a href="http://www.nikopik.com/2013/06/le-fbi-exige-que-tous-les-gadgets-et-logiciels-possedent-un-niveau-de-securite-faible-pour-faire-des-ecoutes.html">Le FBI exige que tous les gadgets et logiciels possèdent un niveau de sécurité faible pour faire des écoutes</a></li></ul>
<br/>
<h3 id="google">Google</h3>
<span style="font-style: italic;">Liste des services et logiciels faussement transparents&nbsp;:</span> Android, Google AdSense, Google AdWords, Google Agenda, Google Analytics, Google Code, Google Docs, Google Drive, Google Fonts, Google Glass, Google Music, Google+, GMail, Google Group, Google Street View, Picasa, Youtube<br/>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[1] [2] [3] [4] [7] [8] [11]</span></li>
<li>2013-03-12&nbsp;: <a href="http://reflets.info/google-la-mise-en-place-de-laspirateur-a-donnees-personnelles/">Google&nbsp;: la mise en place de l’aspirateur à données personnelles</a></li>
<li>2013-06-04&nbsp;: <a href="http://sametmax.com/non-aux-google-glasses/">Non aux Google Glasses</a></li>
<li>2013-08-13&nbsp;: <a href="http://www.sfgate.com/technology/businessinsider/article/GOOGLE-If-You-Use-Gmail-You-Have-No-Legitimate-4730587.php">GOOGLE: If You Use Gmail, You Have 'No Legitimate Expectation Of Privacy'</a></li></ul>
<br/>
<h3 id="hp">HP</h3>
<span style="font-style: italic;">Liste des services et produits impactés&nbsp;:</span> Portables, StoreVirtual (et du coup, très certainement d'autres produits)<br/>
<ul>
<li>2010-12-14&nbsp;:<a href="https://www.securityweek.com/backdoor-vulnerability-discovered-hp-msa2000-storage-systems">Backdoor Vulnerability Discovered on HP MSA2000 Storage Systems</a></li>
<li>2013-07-11&nbsp;: <a href="http://www.theregister.co.uk/2013/07/11/hp_prepping_fix_for_latest_storage_vuln/">HP admits to backdoors in storage products</a></li>
<li>2013-08-30&nbsp;: <a href="http://www.reddit.com/r/RTLSDR/comments/1le3if/so_i_discovered_that_my_hp_laptop_leakstransmits/">So I discovered that my HP laptop leaks/transmits its built-in mic audio somewhere around 24Mhz</a></li></ul>
<br/>
<h3 id="microsoft">Microsoft</h3>
<span style="font-style: italic;">Liste des services, logiciels et consoles faussement transparents&nbsp;:</span> Microsoft Outlook, Microsoft Live, SkyDrive, Skype, XBox One<br/>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[2] [4] [6] [8]</span></li>
<li>2012-06-23&nbsp;: <a href="http://sebsauvage.net/rhaa/index.php?2012/08/23/14/46/48-microsoft-live-n-est-pas-fait-pour-les-etres-humains">Microsoft Live n'est pas fait pour les êtres humains</a></li>
<li>2012-11-06&nbsp;: <a href="http://www.numerama.com/magazine/24199-drm-espion-microsoft-veut-compter-les-spectateurs-chez-vous.html">DRM espion&nbsp;: Microsoft veut compter les spectateurs chez vous&nbsp;!</a></li>
<li>2013-03-09&nbsp;: <a href="http://sebsauvage.net/links/?dhCUyw">Skype pris en flagrant délit d'espionnage des conversations en Chine</a></li>
<li>2013-03-15&nbsp;: <a href="http://tech.slashdot.org/story/13/03/15/1241229/russian-fsb-can-reportedly-tap-skype-calls">Russian FSB Can Reportedly Tap Skype Calls</a></li>
<li>2013-05-14&nbsp;: <a href="http://www.h-online.com/security/news/item/Skype-with-care-Microsoft-is-reading-everything-you-write-1862870.html">Skype with care – Microsoft is reading everything you write</a></li>
<li>2013-05-22&nbsp;: <a href="http://www.presse-citron.net/la-xbox-one-ecoutera-continuellement-vos-conversations">La Xbox One écoutera continuellement vos conversations</a></li>
<li>2013-06-03&nbsp;: <a href="http://www.neowin.net/news/man-arrested-for-child-erotica-stored-on-his-skydrive">Man arrested for child erotica stored on his SkyDrive</a></li>
<li>2013-06-20&nbsp;: <a href="https://www.schneier.com/blog/archives/2013/06/new_details_on.html">New Details on Skype Eavesdropping</a></li>
<li>2013-06-23&nbsp;: <a href="http://www.zdnet.fr/actualites/le-porno-interdit-sur-skydrive-temoignage-d-un-utilisateur-francais-39775346.htm">Le porno interdit sur SkyDrive, témoignage d'un utilisateur français</a></li>
<li>2013-08-24&nbsp;: <a href="http://www.megaleecher.net/Windows_8_Spying_For_NSA">German Security Officers Warns Govt.&nbsp;: Microsoft Windows 8 too ‘dangerous’ to use</a></li></ul>
<br/>
<h3 id="nintendo">Nintendo</h3>
<span style="font-style: italic;">Liste des services, logiciels et consoles faussement transparents&nbsp;:</span> Nintendo 3DS<br/>
<ul>
<li>2012-11-01&nbsp;: <a href="http://www.numerama.com/magazine/27387-nintendo-suspend-sa-messagerie-sur-3ds-les-enfants-se-montraient-leurs-zizis.html">Nintendo suspend sa messagerie sur 3DS. Les enfants se montraient leurs zizis.</a> (on retient surtout que Nintendo a accès à tous vos messages...)</li></ul>
<br/>
<h3 id="nsa">NSA</h3>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[2] [5] [6] [7] [8] [10] [11]</span></li>
<li>2013-06-07&nbsp;: <a href="http://www.numerama.com/magazine/26172-prism-les-francais-concernes-par-l-espionnage-des-geants-du-web.html">PRISM&nbsp;: les Français concernés par l'espionnage des géants du web</a></li>
<li>2013-06-10&nbsp;: <a href="http://www.businessspectator.com.au/news/2013/6/10/technology/obama-identifies-surveillance-effort-trade-security">Obama identifies surveillance effort as a 'trade off' for security</a></li>
<li>2013-08-25&nbsp;: <a href="http://www.framablog.org/index.php/post/2013/08/25/nsa-mathematiques">Lettre ouverte à mes anciens collègues mathématiciens de la NSA</a></li>
<li>2013-09-16&nbsp;: <a href="http://www.tomsguide.fr/actualite/nsa-transactions-bancaires,22556.html">La NSA surveille aussi les cartes bancaires</a></li></ul>
<br/>
<h3 id="twitter">Twitter</h3>
<ul>
<li>2013-07-03&nbsp;: <a href="http://boingboing.net/2013/07/03/twitter-will-allow-advertisers.html">Twitter to allow advertisers to target your browsing history & email addresses</a></li></ul>
<h3 id="yahoo">Yahoo</h3>
<ul>
<li>Références multiples&nbsp;: <span style="font-weight: bold;">[11]</span></li>
<li>2013-06-03&nbsp;: <a href="http://www.zdnet.fr/actualites/yahoo-laissez-nous-lire-vos-emails-ou-switchez-39790961.htm">Yahoo&nbsp;: laissez-nous lire vos emails ou switchez</a></li></ul>
<br/>
<h3 id="autres">Autres services, logiciels</h3>
<span style="font-style: italic;">Liste des services et logiciels faussement transparents, traitres&nbsp;:</span> LG, Snapchat<br/>
<ul>
<li>2013-10-16&nbsp;: <a href="http://nakedsecurity.sophos.com/2013/10/16/snapchat-admits-sharing-images-with-us-law-enforcement/">Snapchat admits sharing images with US law enforcement</a></li>
<li> 2013-11-18&nbsp;: <a href="http://doctorbeet.blogspot.co.uk/2013/11/lg-smart-tvs-logging-usb-filenames-and.html">LG Smart TVs logging USB filenames and viewing info to LG servers</a></li></ul>
<hr />
Dans un registre un peu plus <span style="font-style: italic;">physique</span>, la poste américaine garde des traces de <span style="font-weight: bold;">tous</span> les envois hors du territoire (nom, adresse, et toutes les informations possibles de rappatrier). Vous avez très certainement déjà acheté sur Amazon ou eBay (en autres), non ?<br/>
<ul>
<li>2013-07-03&nbsp;: <a href="http://www.nytimes.com/2013/07/04/us/monitoring-of-snail-mail.html">U.S. Postal Service Logging All Mail for Law Enforcement</a></li></ul>
<hr />
<h3 id="videos">Conférences, vidéos</h3>
<ul>
<li>2013-06-21&nbsp;: <a href="http://www.youtube.com/watch?v=BbkbdYoffX4">Si, vous avez quelque chose à cacher</a>, de <a href="http://pixellibre.net/">Numendil</a></li>
<li>2013-08-13&nbsp;: <a href="https://www.youtube.com/watch?v=E1htQOYEaDU">Comme votre vie peut devenir flippante... en très peu de temps</a></li>
<li>2013-09-25&nbsp;: <a href="https://www.youtube.com/watch?v=ugGqI24J23s">Le hacker Jacob Appelbaum explique le système de surveillance au Parlement européen </a></li></ul>
<hr />
<h3 id="refs">Références multiples</h3>
<ul>
<li><span style="font-weight: bold;">[1]</span> 2013-05-12&nbsp;: <a href="http://boingboing.net/2013/05/12/apple-can-decrypt-iphones-for.html">Apple can decrypt iPhones for cops; Google can remotely "reset password" for Android devices</a></li>
<li><span style="font-weight: bold;">[2]</span> 2013-06-07&nbsp;: <a href="http://www.wikistrike.com/article-le-fbi-a-acces-aux-serveurs-de-google-skype-et-facebook-118329177.html">Le FBI a accès aux serveurs de Google, Skype et Facebook</a></li>
<li><span style="font-weight: bold;">[3]</span> 2013-03-27&nbsp;: <a href="http://yro.slashdot.org/story/13/03/26/2328250/real-time-gmail-spying-a-top-priority-for-fbi-this-year">Real-Time Gmail Spying a 'Top Priority' For FBI This Year</a></li>
<li><span style="font-weight: bold;">[4]</span> 2012-10-13&nbsp;: <a href="http://sebsauvage.net/links/?HFeVuQ">German police monitors Skype, GoogleMail and Facebook chat</a></li>
<li><span style="font-weight: bold;">[5]</span> 2013-06-22&nbsp;: <a href="http://www.wikistrike.com/article-snowden-juge-l-agence-britannique-pire-que-la-nsa-118656221.html">Snowden juge l'agence britannique "pire" que la NSA</a></li>
<li><span style="font-weight: bold;">[6]</span> 2013-07-11&nbsp;: <a href="http://www.guardian.co.uk/world/2013/jul/11/microsoft-nsa-collaboration-user-data">Revealed: how Microsoft handed the NSA access to encrypted messages</a></li>
<li><span style="font-weight: bold;">[7]</span> 2013-08-27&nbsp;: <a href="http://www.framablog.org/index.php/post/2013/08/27/assange-google-nsa">Google et le gouvernement des États-Unis main dans la main selon Julian Assange</a></li>
<li><span style="font-weight: bold;">[8]</span> 2013-09-01&nbsp;: <a href="http://www.bortzmeyer.org/crypto-protection.html">La cryptographie nous protège t-elle vraiment de l'espionnage par la NSA ou la DGSE ?</a></li>
<li><span style="font-weight: bold;">[9]</span> 2013-09-13&nbsp;: <a href="http://www.zdnet.fr/actualites/paypal-va-partager-avec-facebook-criteo-mediaplex-les-donnees-de-ses-utilisateurs-en-opt-out-39793971.htm">PayPal va partager avec Facebook, Criteo, Mediaplex... les données de ses utilisateurs. En opt-out</a></li>
<li><span style="font-weight: bold;">[10]</span> 2013-10-21&nbsp;: <a href="http://www.lemonde.fr/technologies/article/2013/10/21/comment-la-nsa-espionne-la-france_3499758_651865.html">Comment la NSA espionne la France</a></li>
<li><span style="font-weight: bold;">[11]</span> 2013-10-21&nbsp;: <a href="http://www.techdirt.com/articles/20131030/09554125066/nsa-breaks-into-yahoo-googles-data-centers-without-their-knowledge.shtml">NSA Breaks Into Yahoo And Google's Data Centers Without Their Knowledge</a></li></ul>


feed_id: https://tiger-222.fr/?mode=links&id=20131119165732
title: Projet Avatar
uri: Projet-Avatar
url: https://tiger-222.fr/?d=2013/11/19/16/57/32-projet-avatar
content:
J'avais envie de mettre une image à côté de chaque commentaire, mais ne souhaitais pas utiliser un service tiers comme <a href="http://gravatar.com/">Gravatar</a>. J'ai regardé vite fait quelles pouvaient être les autres solutions existantes mais n'ai pas trouvé mon bonheur parmis, entre autres, <a href="http://sebsauvage.net/wiki/doku.php?id=php:vizhash_gd">VizHash GD</a> de Seb, <a href="https://www.libravatar.org/">libravatar</a>, <a href="http://www.splitbrain.org/projects/monsterid">MonsterID</a> et <a href="https://github.com/search?l=PHP&q=identicons">ces dépôts GitHub</a>. Alors voici ma modeste contribution&nbsp;: <a href="https://github.com/BoboTiG/avatar">Avatar</a>.<br/>
<div style="text-align:center;"><img src="media/60a69694.projet-avatar.png" data-original-source="http://tiger-222.fr/img/projet-avatar.png" alt="projet-avatar.png" /><br/>
<span style="color:gray;">Note&nbsp;: commentaire choisi au pseudo-hasard ^^</span></div><br/>
En situation réelle, ça donne <a href="https://tiger-222.fr/index.php?d=2013/09/12/23/23/47-shaarlimagesnet#commentaires">ceci</a> et <a href="https://tiger-222.fr/index.php?d=2013/09/20/01/57/26-#id0071b0">cela</a>.<br/>
<br/>
<hr>
<h2>Comment ça marche</h2>
<br/>
Le code PHP est relativement simple&nbsp;:<br/>
<pre><code class="language-php">class Avatar<br/>
{<br/>
<br/>
    private $length = 80;<br/>
<br/>
    public function __construct($text = 'Tiger-222')<br/>
    {<br/>
        $this->char = strtoupper($text[0]);<br/>
        if ( $this->char &lt; 'A' || $this->char > 'Z' ) {<br/>
            $this->char = '*';<br/>
        }<br/>
<br/>
        $this->color = hash('crc32', $text);  // RGBA<br/>
        $this->filename = sprintf('%s_%s_%d.png',<br/>
            $this->color, $this->char, $this->length);<br/>
<br/>
        if (&nbsp;!is_file($this->filename) ) {<br/>
            $this->create_thumb();<br/>
        }<br/>
        $this->render();<br/>
    }<br/>
<br/>
    private function color($im, $r, $g, $b, $i) {<br/>
        $i *= 3;  // 5 pour 120px<br/>
        $r = $r + $this->diffs[0] * $i;<br/>
        $g = $g + $this->diffs[1] * $i;<br/>
        $b = $b + $this->diffs[2] * $i;<br/>
        return imagecolorallocate($im, $r, $g, $b);<br/>
    }<br/>
<br/>
    private function create_thumb()<br/>
    {<br/>
        $s = $this->length / 4;<br/>
        list($r_, $g_, $b_, $a_) = str_split($this->color, 2);<br/>
        $r = hexdec($r_);<br/>
        $g = hexdec($g_);<br/>
        $b = hexdec($b_);<br/>
        $this->diffs = array(<br/>
            (255 - $r) / $this->length,<br/>
            (255 - $g) / $this->length,<br/>
            (255 - $b) / $this->length<br/>
        );<br/>
        $i = 16;<br/>
<br/>
        $im = imagecreatetruecolor($this->length, $this->length);<br/>
        $color = imagecolorallocate($im, 255, 255, 255);<br/>
        imagefilledrectangle($im, 0, 0, $this->length, $this->length, $color);<br/>
<br/>
        // First row<br/>
        $shift = $s-1;<br/>
        imagefilledrectangle($im, 0*$s+0, 0, 1*$s-1, $shift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 1*$s+1, 0, 2*$s-1, $shift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 2*$s+1, 0, 3*$s-1, $shift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 3*$s+1, 0, 4*$s-1, $shift, $this->color($im, $r, $g, $b, --$i));<br/>
        // Second row<br/>
        $sshift = $s+1;<br/>
        $eshift = 2*$s-1;<br/>
        imagefilledrectangle($im, 3*$s+1, $sshift, 4*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 2*$s+1, $sshift, 3*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 1*$s+1, $sshift, 2*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 0*$s+0, $sshift, 1*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        // Third row<br/>
        $sshift = 2*$s+1;<br/>
        $eshift = 3*$s-1;<br/>
        imagefilledrectangle($im, 0*$s+0, $sshift, 1*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 1*$s+1, $sshift, 2*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 2*$s+1, $sshift, 3*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 3*$s+1, $sshift, 4*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        // Last row<br/>
        $sshift = 3*$s+1;<br/>
        $eshift = 4*$s-1;<br/>
        imagefilledrectangle($im, 3*$s+1, $sshift, 4*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 2*$s+1, $sshift, 3*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 1*$s+1, $sshift, 2*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
        imagefilledrectangle($im, 0*$s+0, $sshift, 1*$s-1, $eshift, $this->color($im, $r, $g, $b, --$i));<br/>
<br/>
        // Paint the letter<br/>
        $size = 50;<br/>
        $angle = 12;<br/>
        $font = './_avatars.ttf';<br/>
        $dim = imagettfbbox($size, $angle, $font, $this->char);<br/>
        $letter_width = max($dim[0], $dim[2], $dim[4], $dim[6]);<br/>
        $letter_height = min($dim[1], $dim[3], $dim[5], $dim[7]);<br/>
        $x = ($this->length - $letter_width) / 2; $x += 2;<br/>
        $y = ($this->length - $letter_height) / 2;<br/>
        // Shadow<br/>
        $rgb = 222;<br/>
        $shadow = 33;<br/>
        if ( ($r + $g + $b) / 3 < 127 ) {<br/>
                $rgb = 33;<br/>
                $shadow = 222;<br/>
        }<br/>
        $color = imagecolorallocate($im, $rgb, $rgb, $rgb);<br/>
        imagettftext($im, $size, $angle, $x-1, $y-1, $color, $font, $this->char);<br/>
        // Letter<br/>
        $color = imagecolorallocate($im, $shadow, $shadow, $shadow);<br/>
        imagettftext($im, $size, $angle, $x, $y, $color, $font, $this->char);<br/>
<br/>
        imagetruecolortopalette($im, false, 255);<br/>
        imagepng($im, $this->filename);<br/>
        imagedestroy($im);<br/>
    }<br/>
<br/>
    private function render()<br/>
    {<br/>
        header('Content-Type: image/png');<br/>
        readfile($this->filename);<br/>
        exit();<br/>
    }<br/>
<br/>
}<br/>
<br/>
$text = isset($_GET['t']) ? $_GET['t']&nbsp;: '*';<br/>
new Avatar($text);</code></pre>
<br/>
Chaque image obtient un dégradé suivant la somme CRC32 du texte passé à la classe <span style="font-weight: bold;">Avatar</span>. Comme les choses sont bien faites, une somme CRC32 est un code héxadécimal de longueur 8. Je m'en sers pour déterminer la couleur de base du dégradé&nbsp;:<br/>
<pre><code class="language-php">Somme CRC32&nbsp;: 81c44142<br/>
Rouge = 0x81 = 129<br/>
Vert  = 0xc4 = 194<br/>
Bleu  = 0x41 = 65<br/>
Alpha = 0x42 = 66<br/>
<br/>
Soit la couleur finale&nbsp;: RGB(129, 194, 65) ou #81c441.</code></pre>
<br/>
J'ignore la valeur <span style="font-style: italic;">alpha</span> puisque le dégradé sera évalué plus tard par un calcul scientifique fort complexe...<br/>
<br/>
<hr>
<h2>Composition de l'image</h2>
<br/>
Une image sera plus compréhensible que des explications fumeuses&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/8b6e129f.projet-avatar-composition.png" data-original-source="http://tiger-222.fr/img/projet-avatar-composition.png" alt="projet-avatar-composition.png" /></div><br/>
À chaque étape, la couleur est redéfinie suivant 16 palliers.<br/>
Par dessus le carré final, s'ajoute la première lettre du texte passé à la classe <span style="font-weight: bold;">Avatar</span>, en majuscule. Ainsi qu'une ombre portée. Les couleurs de la lettre et de l'ombre sont inversées suivant la couleur du carré&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/4625153c.projet-avatar-composition-finale.png" data-original-source="http://tiger-222.fr/img/projet-avatar-composition-finale.png" alt="projet-avatar-composition-finale.png" /></div><br/>
La lettre doit être comprise dans l'alphabet <code class="language-markup">[A-Z*]</code>, mais vous pouvez modifier le code pour accepter toutes les lettres. J'ai mis cette restriction car je me suis servi de <a href="http://fonts.philip.html5.org/">ce service en ligne</a> pour générer le fichier <span style="font-style: italic;">_avatar.ttf</span> ; à vous de faire votre choix ou d'incoporer une police complète.<br/>
<br/>
<hr>
<h2>Intégration</h2>
<br/>
<pre><code class="language-markup">&lt;html>
&lt;head><br/>
    &lt;meta content="utf-8"><br/>
    &lt;title>Avatar&lt;/title><br/>
    &lt;style><br/>
        img {<br/>
            background-color: #fff;<br/>
            padding: 1px;<br/>
            border: 1px outset #111;<br/>
            border-radius: 60px;<br/>
        }<br/>
    &lt;/style><br/>
&lt;/head><br/>
&lt;body><br/>
    &lt;img src="https://tiger-222.fr/avatars/?t=Kevin"/><br/>
    &lt;img src="https://tiger-222.fr/index2.php"/><br/>
&lt;/body><br/>
&lt;/html><br/>
</code></pre>
<br/>
Bien entendu, les images générées sont gardées en cache. Aperçu final&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/3504b939.projet-avatar-2.png" data-original-source="http://tiger-222.fr/img/projet-avatar-2.png" alt="projet-avatar-2.png" /></div><br/>
<hr>
<h2>Améliorations</h2>
<br/>
Dans l'idéal, j'aurai voulu générer la couleur du carré en utilisant l'adresse IP, mais cette information n'est pas gardée dans <a href="http://lehollandaisvolant.net/blogotext/">BlogoText</a>. Et je n'avais pas vraiment l'envie de bidouiller la base de données pour ajouter ne serait ce que le condensat SHA256 de l'adresse IP du commentateur.<br/>
Dans le <a href="https://github.com/BoboTiG/avatar">dépôt GitHub</a>, j'ai ajouté une version qui prend en paramètre l'adresse IP ainsi que la lettre (fichier <span style="font-style: italic;">index2.php</span>). Ça permet d'avoir un pseudonyme différent pour une même adresse IP.<br/>
<br/>
Aussi, si vous trouvez une solution plus courte, une idée d'amélioration ou tout ce que vous voulez, n'hésitez pas à forker et proposer un patch ☺


feed_id: https://tiger-222.fr/?mode=links&id=20131119222610
title: Le port d'armes, z'êtes fou ?!
uri: Le-port-d-armes-z-êtes-fou
url: https://tiger-222.fr/?d=2013/11/19/22/26/10-le-port-darmes-zetes-fou
content:
<div style="text-align:center;"><img src="media/305dc477.v-for-vendetta-mini.jpg" data-original-source="http://tiger-222.fr/img/v-for-vendetta-mini.jpg" alt="v-for-vendetta-mini.jpg" /><br/>
<a href="media/d939ae7e.V-for-Vendetta.jpg" data-original-source="http://www.englishmoviez.com/wp-content/uploads/2011/11/V-for-Vendetta.jpg">Version haute résolution</a> (<a href="media/eb943990.v-for-vendetta.jpg" data-original-source="http://tiger-222.fr/img/v-for-vendetta.jpg">copie locale</a>)</div><br/>
<br/>
En ce moment même le documentaire <a href="http://www.cherie25.fr/programmes-4270/programmetv/episode/16370-des-armes-dans-les-caddies.html">Des armes dans les caddies</a> passe sur Chérie 25&nbsp;:  <span style="font-style: italic;">une enquête menée aux Etats-Unis sur le nombre grandissant des Américaines qui ont choisi de porter une arme pour se défendre</span>.<br/>
<br/>
Ça me sidère&nbsp;! <span style="font-style: italic;">Des femmes avec un flingue ?!</span> Non, <span style="text-decoration: underline;">je plaisante</span> bien entendu. <span style="font-weight: bold;">Des humains avec des armes ?!</span><br/>
<br/>
Bien sûr, ce qui suit n'engage que moi. Et j'en rajoute peut-être un peu (ou pas).<br/>
<br/>
<hr>
<h2>Argumentaire</h2>
<br/>
Les arguments des politiques et des vendeurs ne sont que fumisterie, ça m'enrage de voir la populasse se laisser engrainer si facilement. Le lobby de l'armement est horriblement puissant, certes, mais c'est bien nous (la populasse) qui lui fournissons l'argent et la demande.<br/>
<br/>
Quand je vois des pistolets roses pour plaire aux dames, c'est terriblement malsain, on en vient à moderniser l'arme, tel un gadget à la mode.<br/>
<br/>
Quand j'entends un vendeur dire que cette <span style="font-style: italic;">22</span> bleue plaît énormément aux petits garçons, ça me <span style="font-weight: bold;">tue</span>&nbsp;! Non mais QUOI ?! Personne n'a une once d'intelligence, de raisonnement logique, ou simplement de tête ? Qui peut bien acheter un fusil à son gosse, que peut-il bien en faire ? Un enfant reste un enfant, il n'est pas capable de <a href="media/ca6902b4.enfant-arme.jpg" data-original-source="http://tiger-222.fr/img/enfant-arme.jpg">comprendre</a> ce qu'il fait, <a href="media/8fff3427.enfant-arme-2.jpg" data-original-source="http://tiger-222.fr/img/enfant-arme-2.jpg">il ne se rend pas compte</a> qu'il s'agit d'un <a href="media/0cb38639.enfant-arme-3.jpg" data-original-source="http://tiger-222.fr/img/enfant-arme-3.jpg">engin de mort</a>. De <span style="font-weight: bold;">mort</span>&nbsp;!<br/>
<br/>
Et la <span style="font-weight: bold;">peur</span> ? Cette fameuse peur de voir une bande de gros balèzes débarquer devant chez toi, bazouka à la main, pour te violer, tuer tes enfants, voler tes économies et faire exploser ta baraque... Dur de finir comme ça. Et quand est-ce que vous réfléchissez ? Pas trop, mais juste un minimum. Il y a déjà tellement d'exemples de malades, ou de personnes qui sont juste dans une mauvaise passe, et qui prenne le chemin le plus pitoyable, le plus facile, pour dégommer ses anciens amis, sa famille ou tout autre personne qui, par malchance, se trouvait là.<br/>
Dernier exemple en date&nbsp;: <a href="http://www.businessinsider.com/eddy-vasquez-murdered-2013-11">la mort d'un des chefs exécutif de Grooveshark</a>, Eddy Vasquez, tué par une de ses connaissances de 2 balles dans la poitrine suite à un malentendu à propos d'un sujet. Chez des personnes à peu près cohérentes, on appelle ça une discussion, un dialogue, qui oppose des arguments et des contre-arguments. Pas des balles de pistolet. Il avait 27 ans. 27 pauvres années d'existence qui finissent comme ça, sur un coup de tête (<span style="font-style: italic;">expression</span>).<br/>
<br/>
Au pire, ayez des couilles (filles comprises) et battez-vous à mains nues. Ça défoule bien plus et, en théorie, chacun devrait se réveiller le lendemain matin. Ou sinon, rien ne vaut une bonne batte et un poing américain (<span style="font-style: italic;">ironie</span>).<br/>
<br/>
<hr>
Il y a peut-être pire dans tout ça, c'est que ce genre de peur mis en place par le pouvoir, peut se retrouver dans tous les domaines. Et ce ne sont jamais les gentils qui gagnent. Voyez les pédo-nazis et autres pirates tueurs de bébés phoques pour exterminer la libertée sur Internet. Ça va finir comme dans V pour Vendetta. Pressé.<br/>
<br/>
Voilà, fallait que ça sorte. Surtout ne vous sentez pas concernés quand je dis <span style="font-weight: bold;">vous</span> ou <span style="font-weight: bold;">nous</span>, rien de personnel ☮


feed_id: https://tiger-222.fr/?mode=links&id=20131125121532
title: PHP : l'erreur subtile de l'opérateur ternaire
uri: PHP-l-erreur-subtile-de-l-opérateur-ternaire
url: https://tiger-222.fr/?d=2013/11/25/12/15/32-php-lerreur-subtile-de-loperateur-ternaire
content:
Récemment, j'ai découvert un <a href="https://github.com/BoboTiG/blogotext/commit/18ddd257c3d3e632fd780e39baf21363717e25f4?w=0">bogue</a> dans BlogoText. La ligne incriminée est&nbsp;:<br/>
<pre><code class="language-php">$token = (isset($_POST['token'])) ? $_POST['token']&nbsp;: (isset($_GET['token'])) ? $_GET['token']&nbsp;: 'false';</code></pre>
Soit&nbsp;:<br/>
<pre><code class="language-php">$token =<br/>
    isset($_POST['token']) ?<br/>
        $_POST['token']&nbsp;:<br/>
        isset($_GET['token']) ?<br/>
            $_GET['token']&nbsp;:<br/>
            'false';</code></pre>
<br/>
Il s'agit d'une imbrication de conditions ternaires. Comme le dit <a href="http://php.net/manual/fr/language.operators.comparison.php#language.operators.comparison.ternary">la documentation</a>, l'expression <span style="font-weight: bold;">(expr1) ? (expr2)&nbsp;: (expr3)</span> est évaluée à expr2 si expr1 est évaluée à TRUE, et expr3 si expr1 est évaluée à FALSE.<br/>
<br/>
<div style="text-align:center;"><img src="media/e174e3c0.operateur-ternaire.png" data-original-source="https://tiger-222.fr/img/operateur-ternaire.png" alt="operateur-ternaire.png" /></div><br/>
Ici l'auteur désire récupérer le <span style="font-style: italic;">token</span> envoyé par la méthode <span style="font-style: italic;">POST</span>, ou sinon <span style="font-style: italic;">GET</span>.<br/>
En situation réelle, <span style="font-style: italic;">$_POST</span> contient bien une entrée <span style="font-style: italic;">token</span>, donc nous devrions avoir  <span style="font-style: italic;">$_POST['token']</span>. Hors, l'expression ci-dessus retournera <span style="font-style: italic;">NULL</span>... Voyons pourquoi.<br/>
<br/>
<hr>
L'expression ternaire est évaluée de gauche à droite, pour que ça soit plus clair&nbsp;:<br/>
<pre><code class="language-php">$token =<br/>
    isset($_POST['token']) ?<br/>
        'a'&nbsp;:<br/>
        isset($_GET['token']) ?<br/>
            'b'&nbsp;:<br/>
            isset($_SESSION['token']) ?<br/>
                'c'&nbsp;:<br/>
                isset($je_suis_un_crack) ?<br/>
                    'd':<br/>
                    FALSE;</code></pre>
Que vaut <span style="font-style: italic;">$token</span> dans cet l'exemple ?<br/>
En théorie <span style="font-style: italic;">'a'</span>, puisque <span style="font-style: italic;">$_POST['token']</span> existe. Au lieu de ça, <span style="font-style: italic;">$token</span> vaut <span style="font-style: italic;">'d'</span>. Si je remplace <code class="language-php">isset($_POST['token'])</code> par <code class="language-php">!isset($_POST['token'])</code>, <span style="font-style: italic;">$token</span> faudra <span style="font-style: italic;">FALSE</span>.<br/>
<br/>
Pour simplifier, les expressions du milieu sont ignorées. On aura le résultat de la dernière expression&nbsp;:<br/>
<pre><code class="language-php">$token =<br/>
    isset($_POST['token']) ?<br/>
        //'a'&nbsp;:<br/>
        //isset($_GET['token']) ?<br/>
            //'b'&nbsp;:<br/>
            //isset($_SESSION['token']) ?<br/>
                //'c'&nbsp;:<br/>
                //isset($je_suis_un_crack) ?<br/>
                    'd':<br/>
                    FALSE;</code></pre>
<br/>
<hr>
<a href="media/ddaf810e.mouton-chevelu.jpg" data-original-source="http://tiger-222.fr/img/mouton-chevelu.jpg">Revenons-en à nos moutons</a>, pourquoi <span style="font-style: italic;">NULL</span> est renvoyé ? Car <span style="font-style: italic;">$_POST['token']</span> existe bel et bien, donc d'après la suite de l'expression, on retourne <span style="font-style: italic;">$_GET['token']</span>, qui n'existe pas, donc <span style="font-style: italic;">NULL</span>. D'ailleurs, en activant l'affichage des erreurs, on a bien un averto&nbsp;:<br/>
<span style="font-weight: bold;">Notice</span>: Undefined index: token in <span style="font-weight: bold;">inc/veri.php</span> on line <span style="font-weight: bold;">160</span><br/>
<br/>
Pour corriger le problème, il suffit d'ajouter des parenthèses, comme en maths&nbsp;:<br/>
<pre><code class="language-php">$token = isset($_POST['token']) ? $_POST['token']&nbsp;: (isset($_GET['token']) ? $_GET['token']&nbsp;: 'false');</code></pre>Soit&nbsp;:<br/>
<pre><code class="language-php">$token =<br/>
    isset($_POST['token']) ?<br/>
        $_POST['token']&nbsp;:<br/>
        (isset($_GET['token']) ?<br/>
            $_GET['token']&nbsp;:<br/>
            'false');</code></pre>


feed_id: https://tiger-222.fr/?mode=links&id=20131128133033
title: Comment générer un bon ID pour les flux Atom/RSS
uri: Comment-générer-un-bon-ID-pour-les-flux-Atom-RS
url: https://tiger-222.fr/?d=2013/11/28/13/30/33-comment-generer-un-bon-id-pour-les-flux-atomrss
content:
<q>Ce qui suit est une traduction libre de l'article <a href="http://web.archive.org/web/20110514113830/diveintomark.org/archives/2004/05/28/howto-atom-id">How to make a good ID in Atom</a> de Mark Pilgrim, le vendredi 28 mai 2004.<br/>
Je me suis permis de le compléter avec le flux RSS et mettre à jour une RFC.</q><br/>
Table des matières&nbsp;:<br/>
<ul>
<li> <a href="https://tiger-222.fr/#avant">Avant-propos</a> du traducteur</li>
<li> <a href="https://tiger-222.fr/#introduction">Introduction</a></li>
<li> <a href="https://tiger-222.fr/#nohttp">Pourquoi vous ne devriez pas utiliser le permalien comme ID</a></li>
<li> <a href="https://tiger-222.fr/#nourn">Pourquoi vous ne devriez pas utiliser un URN comme ID</a></li>
<li> <a href="https://tiger-222.fr/#tag">Comment générer un ID à l'aide du Tag URI</a></li>
<li> <a href="https://tiger-222.fr/#other">Autres méthodes pour construire un ID valide</a></li>
<li> <a href="https://tiger-222.fr/#multiple">Que se passe-t-il si la même entrée apparaît dans plusieurs flux ?</a></li>
<li> <a href="https://tiger-222.fr/#summary">Résumé</a></li></ul>
<hr>
<h2 id="avant">Avant-propos</h2>
<br/>
Lorsque l'article fera référence à l'élément &lt;id>, il s'agira soit de l'élément &lt;id> du flux Atom, soit de l'élément &lt;guid> du flux RSS. Et ce, par soucis de lisibilité. Cependant, tout ce qui suit est valable pour les flux Atom comme RSS.<br/>
<br/>
<hr>
<h2 id="introduction">Introduction</h2>
<br/>
Chaque entrée d'un flux Atom/RSS doit avoir un ID globalement unique, dans l'élément &lt;id>. Cela aide les agrégateurs à garder une trace de l'entrée, même si elle est mise à jour. Certains agrégateurs réaffichent les entrées modifiées, d'autres non, d'autres changent au fil du temps. Mais avant de pouvoir faire quoi que ce soit, vous devez identifier chaque entrée de manière unique, et c'est le rôle de &lt;id>.<br/>
<br/>
Il y a 3 conditions requises pour un ID&nbsp;:<br/>
<br/>
<ol>
<li> L'ID doit être un <a href="https://fr.wikipedia.org/wiki/Uniform_Resource_Identifier"><abbr title="Uniform Resource Identifier">URI</abbr></a> valide, tel que défini par la <span style="text-decoration: line-through;"><a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a></span> <a href="http://www.bortzmeyer.org/3986.html">RFC 3986</a>.</li>
<li> L'ID doit être globalement unique, quelque soit le flux Atom/RSS, partout, et pour toujours. Il s'avère que cette partie est plus facile qu'elle n'y paraît.</li>
<li> L'ID ne doit jamais, jamais changer.</li></ol>
<br/>
Il existe plusieurs manières de construire un ID immuable globalement unique, mais certaines sont mieux que d'autres.<br/>
<br/>
<hr>
<h2 id="nohttp">Pourquoi vous ne devriez pas utiliser le permalien comme ID</h2>
<br/>
Le fait d'utiliser l'URL du permalien comme &lt;id> est valide, mais je le déconseille parce qu'il peut porter à confusion sur l'élément qui devrait être traité comme permalien. Les développeurs qui ne lisent pas les spécifications regarderont votre flux Atom/RSS et verront deux éléments d'information identiques, ils en choisiront un comme permalien, et certains se tromperont. Puis il iront vers un autre flux où les deux éléments ne sont pas les mêmes, et seront confus.<br/>
<br/>
Dans un flux Atom/RSS, &lt;link rel="alternate"> est <span style="font-style: italic;">toujours</span> le permalien de l'entrée. &lt;id> est <span style="font-style: italic;">toujours</span> l'unique identifiant de l'entrée. Les deux sont requis, mais ils ont des objectifs différents. L'ID d'une entrée ne devrait jamais changer, même si le permalien est modifié.<br/>
<br/>
«&nbsp;Permalien modifié&nbsp;» ? Oui, les permaliens ne sont pas aussi permanents qu vous pourriez le penser. Voici un exemple qui m'est arrivé. Mes permaliens étaient générés automatiquement d'après le titre de mon entrée, mais plus tard j'ai mis à jour une entrée et modifé le titre. Devinez quoi, l'URL du "permalien" avait changé&nbsp;! Si vous êtes malins, vous pouvez utiliser une redirection HTTP pour rediriger le visiteur depuis un ancien permalien vers le nouveau (ce que j'ai fait). Mais vous ne pouvez pas rediriger un ID.<br/>
<br/>
<span style="font-style: italic;">L'ID d'une entrée Atom/RSS ne doit jamais changer&nbsp;!</span> Dans l'idéal, vous devriez générer l'ID d'une entrée une seule fois, et le stocker quelque part. Si vous le générez automatiquement, à chaque fois que vous apporterez un changement, l'ID de l'entrée sera modifié, ce qui va à l'encontre de l'objectif.<br/>
<br/>
<hr>
<h2 id="nourn">Pourquoi vous ne devriez pas utiliser un URN comme ID</h2>
<br/>
La <a href="http://www.ietf.org/rfc/rfc2141.txt">RFC 2141</a> définie la syntaxe pour les <a href="https://fr.wikipedia.org/wiki/Uniform_Resource_Name"><abbr title="Uniform Resource Name">URN</abbr></a>. Les URN ont été spécialement élaboré pour être utilisés comme identifiant globalement unique. Il s'agit d'URI valides. Ils ressemblent, en quelque sorte, aux URL que vous tapez dans la barre d'adresse d'un naviagteur, à ceci près que les URN ne sont pas déstinés à être cliquable. Ce sont de simples identificateurs structurés.<br/>
<br/>
Alors pourquoi ne pas les utiliser ? Eh bien, la raison principale est qu'ils doivent être enregistrés (comme décrit dans la <a href="http://www.ietf.org/rfc/rfc3406.txt">RFC 3406</a>). Vous ne pouvez pas juste utiliser le nom de domaine que vous avez déjà ; l'enregistrement d'un espace de nom URN est un processus à part.<br/>
<br/>
Si vous avez enregistré un espace de nom URN, alors vous pouvez l'utiliser pour générer des ID. Dans le cas contraire, vous ne pouvez pas simplement utiliser un URN et le publier. Les URN ne fonctionnent pas de cette manière.<br/>
<br/>
<hr>
<h2 id="tag">Comment générer un ID à l'aide du Tag URI</h2>
<br/>
Il y a un standard émergeant qui permet à tout le monde de générer des identifiants globaux uniques sans enregistrement&nbsp;: le <a href="http://www.taguri.org/">Tag URI</a>. Pour en générer un, seuls un nom de domaine et une adresse courriel sont nécessaires. (Un sous-domaine fonctionne aussi.) Pour ce tutoriel, je supposerai que vous possédez votre propre nom de domaine ou sous-domaine, et que vous ne souhaitiez pas divulguer votre adresse courriel aux yeux des spammeurs.<br/>
<br/>
Commençons par l'URL du permalien. J'utiliserait <span style="text-decoration: underline;">http://diveintomark.org/archives/2004/05/27/howto-atom-linkblog</span>, un exemple d'article réel. Votre permalien peut sembler différent, il ne contient peut-être pas de date, ou est composé d'un simple ID numérique ; il peut contenir un identifiant fragmenté (avec la marque #). Pas de soucis, vous pouvez construire un Tag URI à partir de n'importe quelle URL.<br/>
<br/>
<ol>
<li>Jeter tout ce qui précède le nom de domaine&nbsp;:<br/>
<pre><code class="language-markup">diveintomark.org/archives/2004/05/27/howto-atom-linkblog</code></pre></li>
<br/>
<li>Remplacer tous les # par /&nbsp;:<br/>
(dans notre cas, rien ne change)</li>
<br/>
<li>Juste après le nom de domaine, ajoutez une virgule, suivie de l'année-mois-jour de publication de l'article, puis deux-points («&nbsp;:&nbsp;»). Veillez à noter l'année sur 4 chiffres, le mois et le jour sur deux chiffres chacun. N'oubliez pas le deux-points&nbsp;:<br/>
<pre><code class="language-markup">diveintomark.org,2004-05-27:/archives/2004/05/27/howto-atom-linkblog</code></pre></li>
<br/>
<li>Ajoutez <code class="language-markup">tag:</code> au début. (N'ajoutez pas de barres obliques, ou slashes, c'est juste “tag:“. C'est une erreur commune.)&nbsp;:<br/>
<pre><code class="language-markup">tag:diveintomark.org,2004-05-27:/archives/2004/05/27/howto-atom-linkblog</code></pre></li>
</ol>
<br/>
Voilà&nbsp;! Il y a d'autres manières de créer un Tag URI valide, mais cette procédure fonctionne pour toutes les URL.<br/>
<br/>
Le seul problème potentiel que je vois, c'est si votre permalien est amené à changer dans le temps (par exemple, s'il est basé sur le titre et que vous le modifier après publication, ou si vous changer radicalement le schéma URL des permaliens), vous ne devez pas reconstruire le Tag URI à chaque fois que le permalien change. Dans l'idéal, vous devriez générer une seule fois l'ID et le stocker avec le reste des données de l'entrée. Si ça n'est pas faisable, et si vous ne pouvez pas garantir que vos permaliens ne changeront jamais, vous devriez envisager une autre méthode pour générer le Tag URI.<br/>
<br/>
<hr>
<h2 id="other">Autres méthodes pour construire un ID valide</h2>
<br/>
<ul>
<li><span style="font-weight: bold;">Par une quelconque clef interne</span>, telle que la clef primaire de votre entrée dans la table de la base de données. Par exemple, dans <span style="font-style: italic;">Movable Type</span>, l'étiquette modèle &lt;$MTEntryID$> vous donnera la clef primaire de la table <span style="font-style: italic;">mt_entry</span>. Pour une entrée donnée, cette clef ne changera jamais. Ça n'est pas un Tag URI valide à proprement parlé (c'est juste un nombre), mais il peut servir à générer un Tag URI valide. Exemple&nbsp;:<br/>
<pre><code class="language-markup">tag:diveintomark.org,2004-05-27:1192 (ici &lt;$MTEntryID$> vaut 1192)</code></pre>
<br/>
Ici, le seul problème potentiel est un manque de portabilité. Récemment, j'ai changé d'outil de publication, et l'imort/export n'a pas pris en compte ces clefs. Tous les ID de mes entrées ont été modifié. Je suis mauvais. Cette expérience a été en partie ce qui m'a incité à écrire ce tutoriel.<br/>
<br/>
Et bien sûr, si votre outil de publication n'utilise pas de base de données, alors cette technique n'est pas pour vous. Désolé, Rael.</li>
<br/>
<li><span style="font-weight: bold;">Par date de création de l'entrée.</span> Si, dans votre outil de publication, la date des entrées est immuable (autrement dit, une date qui ne change pas lorsque l'entrée est mise à jour, et qui n'est pas modifiable par l'utilisateur final), vous pouvez l'utiliser pour créer un Tag URI. Exemple&nbsp;:<br/>
<pre><code class="language-markup">tag:diveintomark.org,2004-05-27:/archives/20040527110347</code></pre>
<br/>
Dans ce cas, la date de création de l'entrée était 2004-05-27 à 11:03:47. Les espaces ne sont pas autorisés dans un Tag URI, j'ai donc joint ensemble année, mois, jour, heure, minute et seconde.<br/>
<br/>
Ici, le seul problème potentiel est que vous devez garantir à l'avance que deux entrées ne seront pas publiées exactement au même moment. Dès lors, elles partageraient le même ID, ce qui va à l'encontre de l'objectif. Dans le cas d'une utilisation mono-utilisateur, ça n'est généralement pas un soucis ; et c'est ainsi que je génère mes ID désormais.</li>
</ul>
<hr>
<h2 id="multiple">Que se passe-t-il si la même entrée apparaît dans plusieurs flux ?</h2>
<br/>
Si la même entrée apparaît dans deux flux différents, elle doit avoir le même ID dans les deux. Ça n'est pas une exception à la règle "globalement unique", ça en fait partie intégrante. L'ID d'une entrée est la clef de <span style="font-style: italic;">cette entrée</span> à travers le temps et l'espace. Si la même entrée apparaît à deux endroits, elle doit avoir le même ID partout &mdash; sinon ça n'est pas réellement la même entrée.<br/>
<br/>
Quand cela pourrait-il arriver ?<br/>
<br/>
<ul>
<li> Un site web qui classe ses flux par catégories, où une entrée apparaît dans plusieurs catégories</li>
<li> Les flux partagés, comme sur les sites du type «&nbsp;Planet XYZ&nbsp;» qui agrègent le contenu des sites de plusieurs contributeurs.</li></ul>
Dans le cas où un site web propose plusieurs flux, vous devez simplement faire attention à ce que chaque ID généré soit identique quelque soit le flux. Soyez sûr que l'ID ne soit pas basé sur l'URL du flux dans lequel il apparaît, ni du nom de la catégorie, ou tout autre donnée susceptible de différer suivant qu'elle soit dans un flux ou l'autre.<br/>
<br/>
Dans le cas de sites qui agrègent le contenu d'autres sites, le script d'agrégation devrait préserver l'élément &lt;id> original de l'entrée de chaque flux.<br/>
<br/>
Comment les agrégateurs gèrent le duplica de données est à leur entière charge. Si une entrée apparaît dans deux flux, et que vous êtes abonnés aux deux, certains agrégateurs pourrait afficher l'entrée dans les deux, mais la marquer comme "lue" partout lorsque vous l'aurez lue une seule fois. Le comportement du logiciel côté client est entièrement à la merci du développeur qui l'a écrit. La seule chose que fait l'élément &lt;id>, c'est de donner au développeur la capacité de prendre ces décisions sans complications ni erreurs heuristiques.<br/>
<br/>
<hr>
<h2 id="summary">Résumé</h2>
<br/>
Un ID Atom/RSS est <span style="font-weight: bold;">un URI immuable, global et unique</span>. Tous ces attributs sont importants. Si l'ID d'une entrée change constamment, ça va à l'encontre de l'objectif. Si vous réutilisez les ID pour différentes entrées, ça va <span style="font-style: italic;">vraiment</span> à l'encontre du principe. Il y a plusieurs techniques pour construire un URI immuable globalement unique, et vous devriez choisir le plus facile pour vous.<br/>
<br/>
<div style="text-align:center;">§</div>


feed_id: https://tiger-222.fr/?mode=links&id=20131129013225
title: Fix : atikmdag.sys BSOD Windows 7
uri: Fix-atikmdag-sys-BSOD-Windows-7
url: https://tiger-222.fr/?d=2013/11/29/01/32/25-fix-atikmdagsys-bsod-windows-7
content:
<span style="color:red;"><span style="font-weight: bold;">Édit&nbsp;: ça ne fonctionne pas&nbsp;!</span></span><br/>
<hr>
<div style="text-align:center;"><img src="media/183b9a8a.bsod.jpg" data-original-source="http://tiger-222.fr/img/bsod.jpg" alt="bsod.jpg" /><br/>
<span style="color:gray;">Voici le fameux <a href="http://desencyclopedie.wikia.com/wiki/BSOD">Écran Bleu de la Mort</a></span>... Une tuerie&nbsp;!</div><br/>
Ça fait 5-6 fois que le PC portable de mon frangin redémarre tout seul. Juste avant, l'écran devient noir, plus vert, plus bleu, ... Sa carte graphique est une <span style="font-style: italic;">ATI Mobility Radeon HD 4500/5100 Series</span>.<br/>
<br/>
Voici ce que l'outil <a href="http://www.resplendence.com/whocrashed">WhoCrashed</a> nous dit&nbsp;:<br/>
<pre><code class="language-markup">On Thu 28/11/2013 21:49:35 your computer crashed<br/>
This was likely caused by the following module: atikmpag.sys<br/>
Bugcheck code: 0x116 (0xFFFFFA800823E290, 0xFFFFF88004297EFC, 0x0, 0x2)<br/>
Error: VIDEO_TDR_ERROR<br/>
Dump file: C:\Windows\Minidump\112813-16770-01.dmp<br/>
file path: C:\Windows\system32\drivers\atikmpag.sys<br/>
product: AMD driver<br/>
company: Advanced Micro Devices, Inc.<br/>
description: AMD multi-vendor Miniport Driver</code></pre>
<br/>
J'avais déjà mis à jour le pilote, mais il s'avère que ça ne règlera pas le problème. Surtout que la machine ne sert pas à se divertir avec les derniers jeux haute définition, il s'agit d'un outil de travail (bureautique, web, etc).<br/>
<br/>
Je suis tombé sur <a href="http://www.computertipsfree.com/fix-43029-atikmdag-sys-blue-screen-bsod-in-windows-7/">cet article</a> qui explique que le fichier <span style="font-style: italic;">atikmpag.sys</span> n'est jamais mis à jour lors d'une mise à jour du pilote... Ouais, rien que ça. Je n'ai pas vérifié la véracité de la chose, mais rien n'est impossible.<br/>
<br/>
<hr>
Alors voilà la procédure de réparation&nbsp;:<br/>
<br/>
<ol>
<li>Télécharger la dernière version du pilote (l'outil <a href="http://support.amd.com/fr-fr/download/auto-detect-tool">AMD Driver Autodetect</a> peut s'en charger, très pratique)</li>
<li>Décompresser le pilote (généralement dans C:\AMD\Support)</li>
<li>Localiser le fichier <span style="font-style: italic;">atikmpag.sy_</span> et le copier à la racine de C:</li>
<li>Ouvrir une console (<code class="language-markup">Démarrer > Exécuter > cmd</code>), puis&nbsp;:<br/>
<pre><code class="language-markup">&gt; C:<br/>
&gt; expand -r atikmpag.sy_<br/>
&gt; del atikmpag.sy_<br/>
&gt; cd C:\Windows\System32\Drivers\<br/>
&gt; rename atikmpag.sys atikmpag.sys.or<br/>
&gt; rename C:\atikmpag.sys C:\Windows\System32\Drivers\</code></pre>
Pour informations, <a href="http://technet.microsoft.com/fr-fr/library/dd744339%28v=ws.10%29.aspx">expand</a> sert à décompresser un fichier.</li>
</code></pre></li>
</ol>
<br/>
C'est tout bon, il ne vous reste plus qu'à redémarrer&nbsp;!


feed_id: https://tiger-222.fr/?mode=links&id=20140221120520
title: Comment gérer les checkbox multiple non envoyées en POST ?
uri: Comment-gérer-les-checkbox-multiple-non-envoyées-en-POST
url:
https://tiger-222.fr/?d=2014/02/21/12/05/20-comment-gerer-les-checkbox-multiple-non-envoyees-en-post

content:
C'est un cas qui revient assez souvent sur la toile&nbsp;: dans votre formulaire HTML, les cases à cocher ne sont accessibles avec PHP &mdash; dans le tableau <code class="language-php">$_POST</code> &mdash; que si elles sont cochées. Il existe des astuces comme <a href="https://stackoverflow.com/questions/1809494/post-the-checkboxes-that-are-unchecked">ajouté un champ caché</a>, mais dans le cas suivant, ça ne fonctionnera pas (ou la mise en place serait trop fastidieuse).<br/>
<br/>
<hr>
<h2>Le formulaire</h2>
<br/>
Imaginons une <span style="font-style: italic;">todolist</span> toute simple en HTML, avec quelques contrôles en JS et le stockage en PHP.<br/>
<pre><code class="language-markup">&lt;form action="." method="post">
	&lt;table summary="Liste des choses à faire"><br/>
		&lt;tr><br/>
			&lt;th>Tâche&lt;/th><br/>
			&lt;th>Priorité&lt;/th><br/>
			&lt;th>Urgent ?&lt;/th><br/>
		&lt;/tr><br/>
		&lt;tr><br/>
			&lt;td>&lt;input type="text" name="tache[]">&lt;/td><br/>
			&lt;td>&lt;input type="number" name="priorite[]" step="1" min="1" max="5">&lt;/td><br/>
			&lt;td>&lt;input type="checkbox" name="urgent[]">&lt;/td><br/>
		&lt;/tr><br/>
		&lt;!-- (...) plusieurs autres lignes telles que la précédente --><br/>
	&lt;/table><br/>
	&lt;input type="submit" value="Mettre à jour&nbsp;!"><br/>
&lt;/form></code></pre>
<br/>
Dans ce cas là, si j'ajoute 3 choses à faire <span style="font-weight: bold;">non urgentes</span>, le tableau <code class="language-php">$_POST</code> sera rempli tel que&nbsp;:<br/>
<pre><code class="language-php">array(2) {<br/>
  ["tache"]=>
  array(3) {<br/>
    [0]=><br/>
    string(17) "Faire les courses"<br/>
    [1]=><br/>
    string(28) "Corriger bug #2 Shaarlimages"<br/>
    [2]=><br/>
    string(1) "S'abonner à MISC"<br/>
  }<br/>
  ["priorite"]=><br/>
  array(3) {<br/>
    [0]=><br/>
    string(1) "1"<br/>
    [1]=><br/>
    string(1) "4"<br/>
    [2]=><br/>
    string(1) "2"<br/>
  }<br/>
}</code></pre>
<br/>
Maintenant, je coche <span style="font-weight: bold;">urgent</span> pour la tâche n° 2, soit «&nbsp;Corriger bug #2 Shaarlimages&nbsp;». Voyons ce que ça donne&nbsp;:<br/>
<pre><code class="language-php">array(3) {<br/>
  ["urgent"]=>
  array(1) {<br/>
    [0]=><br/>
    string(2) "on"<br/>
  }<br/>
  ["tache"]=><br/>
  array(3) {<br/>
    [0]=><br/>
    string(17) "Faire les courses"<br/>
    [1]=><br/>
    string(28) "Corriger bug #2 Shaarlimages"<br/>
    [2]=><br/>
    string(1) "S'abonner à MISC"<br/>
  }<br/>
  ["priorite"]=><br/>
  array(3) {<br/>
    [0]=><br/>
    string(1) "1"<br/>
    [1]=><br/>
    string(1) "4"<br/>
    [2]=><br/>
    string(1) "2"<br/>
  }<br/>
}</code></pre>
<span style="font-weight: bold;">DOH&nbsp;!</span> La tâche n° 1 se retrouve <span style="font-weight: bold;">urgente</span>, c'est n'importe quoi&nbsp;!<br/>
<br/>
<hr>
<h2>La solution</h2>
<br/>
Lorsque l'on utilise <code class="language-markup">name="tache[]"</code> à la place de <code class="language-markup">name="tache"</code>, le tableau <code class="language-php">$_POST</code> est peuplé d'un tableau contenant les différentes valeurs de tous les champs ayant comme <span style="font-style: italic;">name</span> <code class="language-markup">tache</code>. La premère occurrence sera en tête du tableau. Il y a donc un indice, un curseur, ou appelez ça comme vous voudrez, qui est incrémenté.<br/>
Utilisons ce système à notre avantage alors&nbsp;!<br/>
<br/>
Lorsque l'utilisateur (dé)chochera une case à cocher, on lui affectera la valeur de sont index dans le tableau. Facile&nbsp;:<br/>
<pre data-line="12,13"><code class="language-markup">&lt;form action="." method="post">
	&lt;table summary="Liste des choses à faire"><br/>
		&lt;tr><br/>
			&lt;th>Tâche&lt;/th><br/>
			&lt;th>Priorité&lt;/th><br/>
			&lt;th>Urgent ?&lt;/th><br/>
		&lt;/tr><br/>
		&lt;tr><br/>
			&lt;td>&lt;input type="text" name="tache[]">&lt;/td><br/>
			&lt;td>&lt;input type="number" name="priorite[]" step="1" min="1" max="5">&lt;/td><br/>
			&lt;td><br/>
				&lt;input type="checkbox" name="urgent[]"<br/>
					onChange="this.value = this.parentNode.parentNode.rowIndex;"><br/>
			&lt;/td><br/>
		&lt;/tr><br/>
		&lt;!-- (...) plusieurs autres lignes telles que la précédente --><br/>
	&lt;/table><br/>
	&lt;input type="submit" value="Mettre à jour&nbsp;!"><br/>
&lt;/form></code></pre>
La fonction <a href="http://www.w3schools.com/jsref/prop_tablerow_rowindex.asp">rowIndex</a> retourne l'indice de la ligne dans le tableau.<br/>
<br/>
Dorénavant, voici le contenu du tableau <code class="language-php">$_POST</code> avec la tâche n° 2 <span style="font-weight: bold;">urgente</span>&nbsp;:<br/>
<pre><code class="language-php">array(3) {<br/>
  ["urgent"]=>
  array(1) {<br/>
    [0]=><br/>
    string(1) "1"<br/>
  }<br/>
  ["tache"]=><br/>
  array(3) {<br/>
    [0]=><br/>
    string(17) "Faire les courses"<br/>
    [1]=><br/>
    string(28) "Corriger bug #2 Shaarlimages"<br/>
    [2]=><br/>
    string(1) "S'abonner à MISC"<br/>
  }<br/>
  ["priorite"]=><br/>
  array(3) {<br/>
    [0]=><br/>
    string(1) "1"<br/>
    [1]=><br/>
    string(1) "4"<br/>
    [2]=><br/>
    string(1) "2"<br/>
  }<br/>
}</code></pre>
L'ordre du tableau <span style="font-style: italic;">urgent</span> ne compte plus, il contient seulement les indices des caces cochées.<br/>
<br/>
Et du côté de PHP, pour savoir si une tâche est urgente ou non&nbsp;:<br/>
<pre><code class="language-php">for ( $i = 0, $len = count($_POST['tache']); $i < $len; ++$i ) {<br/>
	$infos[] = array(<br/>
		'tache'    => $_POST['tache'][$i],<br/>
		'priorite' => min(max(1, $_POST['priorite'][$i]+0), 5),<br/>
		'urgent'   => isset($_POST['urgent']) ? in_array($i, $_POST['urgent'])&nbsp;: false,<br/>
	);<br/>
}</code></pre>


feed_id: https://tiger-222.fr/?mode=links&id=20140122214449
title: Livre : Forteresse digitale
uri: Livre-Forteresse-digitale
url: https://tiger-222.fr/?d=2014/01/22/21/44/49-livre-forteresse-digitale
content:
Dans le cadre du <a href="https://tiger-222.fr/index.php?d=2014/01/05/01/47/20-defi-lecture-2014">défi de lecture 2014</a>, voici le bouquin de la semaine <span style="font-weight: bold;">3</span>, gentiment offert par <a href="http://www.ademcan.net/?mode=links">Adem</a> à l'occasion du <a href="http://yome.ch/papa-nawel-surprise-des-shaarlieurs/">Papa Nawel surprise des shaarlieurs</a>&nbsp;:<br/>
<ul>
<li> titre&nbsp;: <span style="text-decoration: underline;">Forteresse digitale</span> (français, 512 pages, format papier)</li>
<li> auteur&nbsp;: Dan Brown</li>
<li> date de 1<sup>ère</sup> parution&nbsp;: 2009</li>
<li> ISBN&nbsp;: 9782253127079</li>
<li> liens&nbsp;: <a href="http://www.livredepoche.com/forteresse-digitale-dan-brown-9782253127079">Le Livre de Poche</a> &mdash; <a href="media/f6d9a4bb.Dan-Brown---Forteresse-digitale.epub" data-original-source="http://tiger-222.fr/files/Dan-Brown---Forteresse-digitale.epub">EPUB</a> &mdash; <a href="https://www.t411.me/torrents/livre-audio-dan-brown-forteresse-digitale-64kbps">livre audio</a></li></ul>
<div style="text-align:center;"><img src="media/0dffd40a.livre_Dan-Brown---Forteresse-digitale.jpg" data-original-source="http://tiger-222.fr/img/livre_Dan-Brown---Forteresse-digitale.jpg" alt="livre_Dan-Brown---Forteresse-digitale.jpg" /></div><br/>
<hr>
À la National Security Agency, l’incroyable se produit. TRANSLTR, le puissant ordinateur de décryptage, ne parvient pas à déchiffrer un nouveau code. Appelée à la rescousse, Susan Fletcher, la belle et brillante cryptanalyste, comprend qu’une terrible menace pèse sur tous les échelons du pouvoir. La NSA est prise en otage par l’inventeur d’un cryptage inviolable qui, s’il était mis sur le marché, pulvériserait tout le système de renseignement américain&nbsp;! Emportée dans un tourbillon de secrets et de faux-semblants, Susan se bat pour protéger son pays et sortir l’agence de ce piège.<br/>
Bientôt trahie par tous, c’est sa propre vie qu’elle devra défendre ainsi que celle de l’homme qu’elle aime.<br/>
<br/>
<hr>
Bien que Dan Brown l'ai écrit en 1998, il avait de la suite dans les idées, ou de bons informateurs... J'ai l'impression de lire un rapport romancé de <a href="https://fr.wikipedia.org/wiki/Jacob_Appelbaum">Jacob Appelbaum</a> suite aux révélations d'<a href="https://fr.wikipedia.org/wiki/Edward_Snowden">Edward Snowden</a>&nbsp;! Vraiment passionnant, l'histoire ne connait aucun "mou", les personnages sont attachants et le dernier tiers se lit à vitesse grand V tellement c'est prenant.<br/>
Les sujets abordés sont, vous l'aurez compris, la surveillance de masse, la mort de la vie privée pour justifier la protection d'un pays et le sabotage d'algorithmes de chiffrement... Bienvenue en 2014&nbsp;! Qui plus est, ça se laisse très bien lire, même pour les non initié(e)s.<br/>
<p style="visibility:hidden" id="petit-voyeur-dechiffre-ca-si-tu-le-peux">113-19-5-28-5-53-66-113-76-19-128-10-92-15-19-128</p>
Livre suivant&nbsp;: <span style="text-decoration: underline;"><a href="https://fr.wikipedia.org/wiki/Le_Horla_%28recueil%29">Le Horla</a></span>, de Guy de Maupassant.


feed_id: https://tiger-222.fr/?mode=links&id=20140120030352
title: Pot de miel en vue sur le port 22
uri: Pot-de-miel-en-vue-sur-le-port-22
url: https://tiger-222.fr/?d=2014/01/20/03/03/52-pot-de-miel-en-vue-sur-le-port-22
content:
Un pot de miel (honeypot en anglais) est un moyen efficace de piéger les attaquants d'un système en leur faisant croire qu'ils ont réussi. Il est alors possible de voir et comprendre comment ils ont fait. Cela s'appelle de la <span style="font-weight: bold;">défense active</span>.<br/>
<br/>
<div style="text-align:center;"><img src="media/289bf9d0.drunk-bee.jpg" data-original-source="http://tiger-222.fr/img/drunk-bee.jpg" alt="drunk-bee.jpg" /><br/>
<span style="color:gray;">«&nbsp;Argh... meehh&nbsp;! Tu sais où tu peux t'le mettre ton dard ‽&nbsp;»</span></div><br/>
<br/>
Faisons un test avec SSH qui, par défaut, utilise le port 22. <a href="https://code.google.com/p/kippo/">Kippo</a> est le pot de miel parfait pour ça&nbsp;!<br/>
<br/>
<hr>
<h2>Installation</h2>
<br/>
Avant toute chose, redirigez le port 22 de votre routeur pour qu'il pointe vers le port 2222 (par défaut) de votre machine, ensuite&nbsp;:<br/>
<pre><code class="language-bash">$ sudo aptitude install python-twisted<br/>
$ wget <a href="https://kippo.googlecode.com/files/kippo-0.8.tar.gz">https://kippo.googlecode.com/files/kippo-0.8.tar.gz</a><br/>
$ tar xzf kippo-0.8.tar.gz<br/>
$ cd kippo-0.8</code></pre>
<br/>
<hr>
<h2>Paramétrage</h2>
<br/>
Dans le fichier <span style="font-weight: bold;">kippo.cfg</span>, vous pouvez ajuster quelques options pour faire plus vrai, comme <code class="language-markup">hostname</code> et <code class="language-markup">banner_file</code>. Le premier sert à définir le nom de la machine et le second à afficher la bannière de connexion, généralement le contenu de <span style="font-style: italic;">/etc/motd</span>. Exemple&nbsp;:<br/>
<pre><code class="language-bash">
             `` Le serveur à la s@uce... ,,<br/>
       _@-@_           ____        _         _____ _  ____        .----.   @   @<br/>
     _(-._.-)_        | __ )  ___ | |__   __|_   _(_)/ ___|      / .-"-.`.  \v/<br/>
  .-(  `---'  )-.     |  _ \ / _ \| '_ \ / _ \| | | | |  _       | | '\ \ \_/ )<br/>
 __\ \\\___/// /__    | |_) | (_) | |_) | (_) | | | | |_| |    ,-\ `-.' /.'  /<br/>
'-._.'/M\ /M\`._,-`   |____/ \___/|_.__/ \___/|_| |_|\____|   '---`----'----'<br/>
<br/>
<br/>
</code></pre>
<br/>
Dans le fichier <span style="font-weight: bold;">data/userdb.txt</span>, vous pouvez ajouter d'autres couples <span style="font-style: italic;">utilisateur:mot de passe</span>.<br/>
<br/>
<hr>
<h2>Exécution et éclate</h2>
<br/>
Pour démarrer le pot de miel, il suffit de faire&nbsp;:<br/>
<pre><code class="language-bash">$ ./start.sh</code></pre>
<br/>
Et pour vous fendre la gueule, vous pouvez revivre les différentes attaques&nbsp;:<br/>
<pre><code class="language-bash">$ python utils/playlog.py log/tty/aaaammdd-hhmmss-XXXX.log</code></pre>
<br/>
<br/>
Sources&nbsp;: <a href="http://bredsaal.dk/running-an-ssh-honeypot-with-debian-and-kippo">Running an SSH honeypot with Debian and Kippo</a> et <a href="http://bruteforce.gr/installing-kippo-ssh-honeypot-on-ubuntu.html"> Installing Kippo SSH Honeypot on Ubuntu </a>


feed_id: https://tiger-222.fr/?mode=links&id=20140120005602
title: Installer BitTorrent Sync
uri: Installer-BitTorrent-Sync
url: https://tiger-222.fr/?d=2014/01/20/00/56/02-installer-bittorrent-sync
content:
<a href="http://www.bittorrent.com/intl/fr/sync">BitTorrent Sync</a> est un outil de synchronisation sécurisée de fichiers, du pair à pair chiffré en AES 256, disponible sur les plateformes Windows, Mac OSX et GNU/Linux. Un concurrent non libre et non open-source à Droppox, Google Drive et consorts.<br/>
<hr>
<h2>Installation</h2>
<br/>
Récupérer la dernière version depuis la <a href="http://www.bittorrent.com/intl/fr/sync/downloads">page des téléchargements</a>, décompresser l'archive obtenue, puis placer l'exécutable <span style="font-weight: bold;">btsync</span> dans <span style="font-style: italic;">/usr/local/bin/</span>.<br/>
<br/>
<hr>
<h2>Configuration</h2>
<br/>
Admettons qu'un volume TrueCrypt soit monté dans <span style="font-style: italic;">/media/trucrypt1</span> et que nous voulions stocker les informations de configuration dans celui-ci, voici les commandes à effectuer&nbsp;:<br/>
<pre><code class="language-bash">$ mkdir /media/trucrypt1/.sync<br/>
$ btsync --dump-sample-config &gt; /media/trucrypt1/.sync/sync.conf</code></pre>
<br/>
Éditer le fichier nouvellement créer et y ajouter&nbsp;:<br/>
<pre><code class="language-javascript">{<br/>
    "device_name": "Tiger-222",<br/>
    "listening_port"&nbsp;: 2048,  // 0 - port aléatoire<br/>
    "storage_path"&nbsp;: "/media/truecrypt1/.sync",<br/>
    "check_for_updates"&nbsp;: false,<br/>
    "use_upnp"&nbsp;: false,<br/>
    "download_limit"&nbsp;: 0,<br/>
    "upload_limit"&nbsp;: 0,<br/>
    "webui"&nbsp;: {<br/>
        "listen"&nbsp;: "0.0.0.0:8888",<br/>
        "login"&nbsp;: "identifiant",<br/>
        "password"&nbsp;: "mot de passe"<br/>
    }<br/>
}</code></pre>
Ne pas oublier de rediriger le port, <code class="language-javascript">2048</code> dans cet exemple. Le nom des options est assez compréhensible, mais si vous bloquez, n'hésitez pas à demander.<br/>
<br/>
<hr>
<h2>Exécution</h2>
<br/>
Il suffira d'appeler btsync avec le fichier de configuration désiré&nbsp;:<br/>
<pre><code class="language-bash">$ btsync --config /media/trucrypt1/.sync/sync.conf<br/>
# BitTorrent Sync forked to background. pid = xxxx</code></pre>
<br/>
L'interface web est désormais accessible à <a href="http://127.0.0.1:8888">http://127.0.0.1:8888</a>, vous pouvez modifier la langue et ajouter des dossiers de partage (création, ajout avec clef secrète, etc.).<br/>
<br/>
<div style="text-align:center;"><img src="media/24b5756d.btsync.png" data-original-source="http://tiger-222.fr/img/btsync.png" alt="btsync.png" /></div><br/>
<hr>
<h2>.SyncIgnore</h2>
<br/>
Si certains fichiers d'un dossier partagé ne doivent pas l'être, créer le fichier <span style="font-weight: bold;">.SyncIgnore</span> dans ce dossier et ajouter un motif par ligne&nbsp;:<br/>
<pre><code class="language-markup">*.bak<br/>
~*<br/>
dossier/confidentiel.odt</code></pre>
<br/>
Lien vers la <a href="media/7046c427.BitTorrentSyncUserGuide.pdf" data-original-source="http://btsync.s3-website-us-east-1.amazonaws.com/BitTorrentSyncUserGuide.pdf">documentation officielle</a>.


feed_id: https://tiger-222.fr/?mode=links&id=20140112213000
title: Live : Dans la peau d'un informaticien expert judiciaire - L’âge d’or est devant nous
url:
https://tiger-222.fr/?d=2014/01/12/21/30/00-live-dans-la-peau-dun-informaticien-expert-judiciaire---lage-dor-est-devant-nous

content:
Dans le cadre du <a href="https://tiger-222.fr/index.php?d=2014/01/05/01/47/20-defi-lecture-2014">défi de lecture 2014</a>, voici le bouquin de la semaine <span style="font-weight: bold;">2</span>&nbsp;:<br/>
<ul>
<li> titre&nbsp;: <span style="text-decoration: underline;">Dans la peau d'un informaticien expert judiciaire - L’âge d’or est devant nous</span> (français, 186 pages, format électronique)</li>
<li> auteur&nbsp;: Zythom</li>
<li> date de 1<sup>ère</sup> parution&nbsp;: 2007</li>
<li> ISBN&nbsp;: 9781847998774</li>
<li> liens&nbsp;: <a href="http://www.lulu.com/shop/zythom/zythom-dans-la-peau-dun-informaticien-expert-judiciaire/paperback/product-18950596.html">Seconde Edition</a> &mdash; <a href="http://zythom.blogspot.fr/2012/03/dans-la-peau-dun-informaticien-expert.html">PDF, EPUB, FB2, LIT, LRF &amp; MOBI</a> (<a href="http://tiger-222.fr/files/zythom_T1.zip">copie locale</a>)</li></ul>
<div style="text-align:center;"><img src="media/227fff0f.livre_zythom_T1.jpg" data-original-source="http://tiger-222.fr/img/livre_zythom_T1.jpg" alt="livre_zythom_T1" /></div><br/>
<hr>
Ce livre est un recueil d'articles croustillants publiés par le génialissime <a href="http://zythom.blogspot.fr">Zythom</a>, un informaticien qui endosse la parfois difficile activité d'expert judiciaire. Comme nous pouvons nous en douter, il s'agit en grande partie de faits divers en relation avec l'expertise judiciaire dans le domaine de l'informatique... et  c'est passionnant&nbsp;! Ça permet de découvrir un univers assez opaque où il faut gérer plusieurs parties (comprenez personnes ou représentants), s'intéresser un minimum au droit, rester pédagogue tout en étant à la pointe dans son domaine. Bref, ça n'est pas de tout repos, mais c'est raconté avec légèreté, sérieux et humour.<br/>
Le plus dur dans l'histoire, c'est lorsqu'il raconte ses expertises liées à la pédopornographie&nbsp;: je lui tire mon chapeau, car devoir visionner 3 000 photos et vidéos dans le weekend, ça doit être éreintant et assez désespérant. Mais, comme Zythom le dit si bien, il sauve des vies en contrepartie.<br/>
<br/>
Aller, voici un petit extrait complètement décalé&nbsp;:<br/>
<q>Le mot "coaltar" signifie "goudron de houille". Cette substance est utilisée pour imprégner les bois et en thérapeutique comme désinfectant et antiseptique.<br/>
<br/>
Je n'avais jamais vu ce mot écrit et n'en connaissais pas l'orthographe. C'est pourtant un mot souvent utilisé, par oral, dans l'expression "Etre dans le coaltar".</q><br/>
Si cet univers vous intéresse, Zythom a donné une conférence forte intéressante lors des JRES 2013&nbsp;: <a href="https://www.youtube.com/watch?v=NEgy7ZO9s30">https://www.youtube.com/watch?v=NEgy7ZO9s30</a>.<br/>
<br/>
<br/>
Livre suivant&nbsp;: <span style="text-decoration: underline;"><a href="https://fr.wikipedia.org/wiki/Forteresse_digitale">Forteresse Digitale</a></span>, de Dan Brown (gentiment offert par <a href="http://www.ademcan.net/?mode=links">Adem</a>, mon Papa Nawel chéri).


feed_id: https://tiger-222.fr/?mode=links&id=20140106005832
title: Livre : La Mort est mon Métier
uri: Livre-La-Mort-est-mon-Métier
url: https://tiger-222.fr/?d=2014/01/06/00/58/32-livre-la-mort-est-mon-metier
content:
Dans le cadre du <a href="https://tiger-222.fr/index.php?d=2014/01/05/01/47/20-defi-lecture-2014">défi de lecture 2014</a>, voici le bouquin de la semaine <span style="font-weight: bold;">1</span>&nbsp;:<br/>
<ul>
<li> titre&nbsp;: <span style="text-decoration: underline;">La Mort est mon Métier</span> (français, 384 pages, format papier)</li>
<li> auteur&nbsp;: Robert Merle</li>
<li> date de 1<sup>ère</sup> parution&nbsp;: 1952</li>
<li> ISBN&nbsp;: 9782070367894</li>
<li> liens&nbsp;: <a href="http://www.gallimard.fr/Catalogue/GALLIMARD/Folio/Folio/La-mort-est-mon-metier">Gallimard</a> &mdash; <a href="https://fr.wikipedia.org/wiki/La_mort_est_mon_m%C3%A9tier">Wikipédia</a> &mdash; <a href="media/ecd316cd.livre_Robert-Merle---La-Mort-est-mon-Metier.epub" data-original-source="http://tiger-222.fr/files/livre_Robert-Merle---La-Mort-est-mon-Metier.epub">EPUB</a> &mdash; <a href="http://www.t411.me/torrents/audio-livre-robert-merle-la-mort-est-mon-metier-ska-mp3128kbps">livre audio</a></li></ul>
<div style="text-align:center;"><img src="media/784b9a28.livre_Robert-Merle---La-Mort-est-mon-Metier.jpg" data-original-source="http://tiger-222.fr/img/livre_Robert-Merle---La-Mort-est-mon-Metier.jpg" alt="livre_Robert-Merle---La-Mort-est-mon-Metier.jpg" /></div><br/>
<hr>
Ce livre est une biographie romancée de Rudolf Lang (Rudolf Höß de son vrai nom, prononcé <span style="font-style: italic;">Heuss</span>), le commandant du camp de concentration et d'extermination d'Auschwitz pendant la Seconde Guerre mondiale.<br/>
<q>L’essentiel de sa vie nous est connu par le psychologue américain Gilbert qui l’interrogea dans sa cellule au moment du procès de Nuremberg. Le bref résumé de ces entretiens – que Gilbert voulut bien me communiquer – est dans l’ensemble infiniment plus révélateur que la confession écrite plus tard par Hoess lui-même dans sa prison polonaise. <span style="font-weight: bold;">-- Extrait de la préface de Robert Merle, en 1972.</span></q><div style="text-align:center;"><img src="media/8422d7c8.Rudolf_Hosz.jpg" data-original-source="http://tiger-222.fr/img/Rudolf_Hosz.jpg" alt="Rudolf_Hosz.jpg" /><br/>
<span style="color:gray;">Rudolf Höss lors de son procès en 1947.</span></div><br/>
<hr>
J'ai vite été absorbé par cet ouvrage, il est toujours intéressant de voir comment se passaient les choses vues de l'intérieur, mais ce qui m'a marqué, c'est de voir comment l'éducation d'un enfant peut avoir comme répercussions sur sa vie future. Rudolf eut une éducation à la dure, avec un père très strict qui avait une emprise totale sur lui. Il était dicté par des principes, notamment la loi et la religion, et aucune raison ne pouvait l'en écarter.<br/>
Sans en dire trop, c'est ainsi qu'il gravira tous les échelons de la Schutzstaffel (la fameuse SS, ou escadron de protection) pour être à la tête du tristement célèbre camp de concentration d'Auschwitz, car les lois des dirigeants (Hitler, Himmler et ses différents supérieurs) ne pouvaient être que vraies et aucune personne sur terre n'aurait pu l'en détourner. C'est donc tout naturellement qu'il travaillât à mettre au point et améliorer la <span style="font-style: italic;">solution finale</span>...<br/>
<br/>
<br/>
Livre suivant&nbsp;: <span style="text-decoration: underline;"><a href="http://zythom.blogspot.fr/2012/03/dans-la-peau-dun-informaticien-expert.html">Dans la peau d'un informaticien expert judiciaire - L’âge d’or est devant nous</a></span>, de Zythom.


feed_id: https://tiger-222.fr/?mode=links&id=20140105014720
title: Défi lecture 2014 !
uri: Défi-lecture-2014
url: https://tiger-222.fr/?d=2014/01/05/01/47/20-defi-lecture-2014
content:
Avant toute chose, <span style="font-style: italic;">bonne année</span>&nbsp;!<br/>
<br/>
Ensuite, en cette nouvelle année, je n'ai pris aucune résolution (c'est très bien ainsi). Ceci dit, ce que <a href="http://blog.bleiddwn.com/?d=2014/01/04/20/47/30-defi-lecture-2014">Bleiddwn à proposé sur son blog</a> m'intéresse beaucoup&nbsp;: lire un livre par semaine et écrire un article pour y partager mes impressions, un résumé, une critique, un avis, une réflexion que celà m'a apporté, une photo sexy, etc..<br/>
<div style="text-align:center;"><img src="media/8c0d8bd6.bronson.gif" data-original-source="https://tiger-222.fr/img/bronson.gif" alt="bronson.gif" /><br/>
<span style="color:gray;">Aucun rapport avec l'article, j'adore juste cet acteur (Tom Hardy dans le rôle de Charles Bronson)</span></div><br/>
Je vais tacher de suivre <a href="http://tomcanac.com/blog/2014/01/05/defi-lecture-2014/">Tom</a> et essayerai de vous proposer en téléchargement un fichier EPUB, PDF ou, au pire, un lien vers l'éditeur.<br/>
Pour ceux et celles qui cherchent inspiration, <a href="http://ilovethehost.skyrock.com/">Jessica</a> propose tout un tas de livres numériques sur son <a href="https://skydrive.live.com/?cid=5a781feef5b991d6&id=5A781FEEF5B991D6!108">SkyDrive</a>. Aussi, il y a toujours les bonnes vieilles bibliothèques ou le bouche à oreille avec les voisins/amis/famille/pape.<br/>
<br/>
Pour information, le bouquin de la 1<sup>ère</sup> semaine est <span style="text-decoration: underline;"><a href="https://fr.wikipedia.org/wiki/La_mort_est_mon_m%C3%A9tier">La mort est mon métier</a></span>, de Robert Merle.<br/>
<br/>
Sur ce, bonne lecture, et libérez votre esprit ☺


feed_id: https://tiger-222.fr/?mode=links&id=20131220132057
title: Webdesign : InK et Leaflet, pas d'images ‽
uri: Webdesign-InK-et-Leaflet-pas-d-images
url: https://tiger-222.fr/?d=2013/12/20/13/20/57-webdesign-ink-et-leaflet-pas-dimages
content:
Si vous utilisez le framework <a href="http://ink.sapo.pt/">InK</a> et que vous souhaitez afficher une carte à l'aide de l'excellent <a href="http://leafletjs.com/">Leaflet</a>, aucune image ne sera affichée.<br/>
<br/>
Pour remédier à ce problème, ajoutez ces directives CSS (pensez à adapter l'ID <code class="language-css">#map</code>)&nbsp;:<br/>
<pre><code class="language-css">#map img {<br/>
	margin: 0;<br/>
	max-height: 256px<br/>
}</code></pre>
<br/>
Avant/après&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/4f61d1ab.ink-leaflet-ko.png" data-original-source="http://tiger-222.fr/img/ink-leaflet-ko.png" alt="ink-leaflet-ko.png" /></div><br/>
<div style="text-align:center;"><img src="media/74b534cc.ink-leaflet-ok.png" data-original-source="http://tiger-222.fr/img/ink-leaflet-ok.png" alt="ink-leaflet-ok.png" /></div><br/>
<br/>
Et voilà&nbsp;!


feed_id: https://tiger-222.fr/?mode=links&id=20131218151516
title: WordPress : comment afficher une image différente suivant la page demandée ?
uri: WordPress-comment-afficher-une-image-différente-suivant-la-page-dem
url:
https://tiger-222.fr/?d=2013/12/18/15/15/16-wordpress-comment-afficher-une-image-differente-suivant-la-page-demandee

content:
Pour ce faire, il faut d'abord sélectionner une <i>Image à la Une</i> (<i>Set Featured Image</i> en anglais) pour la page souhaitée, puis éditer le fichier du thème actuel qui gère l'entête des pages.<br/>
<br/>
Exemple avec le thème <a href="http://www.elegantthemes.com/gallery/nimble/">Nimble</a>&nbsp;: le fichier à modifier est <span style="font-style: italic;">top_info.php</span> (l'éditeur de fichiers se trouve dans <code class="language-markup">Apparence</code> > <code class="language-markup">Éditeur</code>). Placer le code suivant juste avant la fermeture de l'avant-dernière <code class="language-markup">div</code>&nbsp;:<br/>
<pre><code class="language-php">if ( has_post_thumbnail() ) {<br/>
	$img = wp_get_attachment_image_src( get_post_thumbnail_id( get_the_ID() ), 'full' );<br/>
	printf( '&lt;img src="https://tiger-222.fr/%s" alt="%s" width="%d" height="%d" style="%s"/>',<br/>
		$img[0], get_the_title(), $img[1], $img[2],<br/>
		'width:auto; max-width:100%;' );<br/>
	unset($img);<br/>
}</code></pre>
Ce code vérifie la présence d'une image associée à la page et récupère un tableau (<code class="language-php">$img</code>) contenant le lien direct ainsi que les dimensions.<br/>
<br/>
Comme ceci, vous aurez le titre de la page, suivi d'un éventuel sous-titre, puis de l'image en taille originale. En bonus, l'image est responsive ☺


feed_id: https://tiger-222.fr/?mode=links&id=20131130163744
title: Vivre, ce n'est pas travailler
uri: Vivre-ce-n-est-pas-travailler
url: https://tiger-222.fr/?d=2013/11/30/16/37/44-vivre-ce-nest-pas-travailler
content:
Je dirai même plus&nbsp;: vivre, c'est avant tout d'être libre. Libre de faire ce que l'on souhaite, tout est respectant l'autre.<br/>
<br/>
<q><span style="text-decoration: underline;">Quels sont les gros cailloux dans votre vie ?</span><br/>
<br/>
Un jour, un vieux professeur de l'École Nationale d'Administration Publique (ENAP) fut engagé pour donner une formation sur la planification efficace de son temps à un groupe d'une quinzaine de dirigeants de grosses compagnies nord-américaines. Ce cours constituait l'un des cinq ateliers de leur journée de formation. Le vieux prof n'avait donc qu'une heure pour faire passer sa matière.<br/>
<br/>
Debout, devant ce groupe d'élite (qui était prêt à noter tout ce que l'expert allait enseigner), le vieux prof les regarda un par un, lentement, puis leur dit&nbsp;: «&nbsp;Nous allons réaliser une expérience&nbsp;».<br/>
<br/>
De dessous la table qui le séparait de ses élèves, le vieux prof sortit un immense pot Mason d'un gallon (pot de verre de plus de 4 litres) qu'il posa délicatement en face de lui. Ensuite, il sortit environ une douzaine de cailloux à peu près gros comme des balles de tennis et les plaça délicatement, un par un, dans le grand pot. Lorsque le pot fut rempli jusqu'au bord et qu'il fut impossible d'y ajouter un caillou de plus, il leva lentement les yeux vers ses élèves et leur demanda&nbsp;: «&nbsp;Est-ce que ce pot est plein ?&nbsp;» Tous répondirent&nbsp;: «&nbsp;Oui&nbsp;».<br/>
<br/>
Il attendit quelques secondes et ajouta&nbsp;: «&nbsp;Vraiment ?&nbsp;» Alors, il se pencha de nouveau et sortit de sous la table un récipient rempli de gravier. Avec minutie, il versa ce gravier sur les gros cailloux puis brassa légèrement le pot. Les morceaux de gravier s'infiltrèrent entre les cailloux jusqu'au fond du pot.<br/>
<br/>
Le vieux prof leva à nouveau les yeux vers son auditoire et redemanda&nbsp;: «&nbsp;Est-ce que ce pot est plein ?&nbsp;» Cette fois, ses brillants élèves commençaient à comprendre son manège. L'un d'eux répondit&nbsp;: «&nbsp;Probablement pas&nbsp;!&nbsp;»<br/>
<br/>
- Bien&nbsp;! répondit le vieux prof. Il se pencha de nouveau et cette fois, sortit de sous la table une chaudière de sable. Avec attention, il versa le sable dans le pot. Le sable alla remplir les espaces entre les gros cailloux et le gravier.<br/>
<br/>
Encore une fois, il demanda&nbsp;: «&nbsp;Est-ce que ce pot est plein ?&nbsp;» Cette fois, sans hésiter et en chœur, les brillants élèves répondirent&nbsp;: «&nbsp;Non&nbsp;!&nbsp;»<br/>
<br/>
- Bien&nbsp;! répondit le vieux prof. Et comme s'y attendaient ses prestigieux élèves, il prit le pichet d'eau qui était sur la table et remplit le pot jusqu'à ras bord.<br/>
<br/>
Le vieux prof leva alors les yeux vers son groupe et demanda&nbsp;: «&nbsp;Quelle grande vérité nous démontre cette expérience ?&nbsp;» Pas fou, le plus audacieux des élèves, songeant au sujet de ce cours, répondit&nbsp;: «&nbsp;Cela démontre que même lorsque l'on croit que notre agenda est complètement rempli, si on le veut vraiment, on peut y ajouter plus de rendez-vous, plus de choses à faire&nbsp;».<br/>
<br/>
- Non&nbsp;! répondit le vieux prof, ce n'est pas cela. La grande vérité que nous démontre cette expérience est la suivante&nbsp;: si on ne met pas les gros cailloux en premier dans le pot, on ne pourra jamais les faire entrer tous, ensuite... Il y eut un profond silence, chacun prenant conscience de l'évidence de ces propos.<br/>
<br/>
Le vieux prof leur dit alors&nbsp;: «&nbsp;Quels sont les gros cailloux dans votre vie ? Votre santé ? Votre famille ? Vos ami(e)s? Réaliser vos rêves ? Faire ce que vous aimez ? Apprendre ? Défendre une cause ? Relaxer ? Prendre le temps ? ou toute autre chose ?<br/>
<br/>
Ce qu'il faut retenir, c'est l'importance de mettre ses <span style="font-weight: bold;">gros cailloux</span> en premier dans sa vie, sinon on risque de ne pas réussir sa vie. Si on donne priorité aux peccadilles (le gravier, le sable), on remplira sa vie de peccadilles et on n'aura plus suffisamment de temps précieux à consacrer aux éléments impor­tants de sa vie. Alors, n'oubliez pas de vous poser à vous-même la question&nbsp;: quels sont les <span style="font-weight: bold;">gros cailloux</span> dans ma vie ? Ensuite, mettez-les en premier dans votre pot (vie)&nbsp;».<br/>
<br/>
D'un geste amical de la main, le vieux professeur salua son auditoire et lentement quitta la salle.</q><br/>
<h2>Quels sont les gros cailloux dans ma vie ?</h2>
<br/>
Avant tout ma famille.<br/>
Ensuite viennent mes amis, faire ce que j'aime (geek rugbyman), et être curieux. La curiosité, c'est l'envie d'apprendre, faire des rencontre (<a href="http://blog.lefigaro.fr/hightech/2008/01/definition-irl.html">IRL</a> ou non), ne pas s'enfermer dans des préjugés, découvrir et, implicitement, se remettre en question&nbsp;: une étape très importante et régulière dans la vie d'une personne, ou en tout cas, ça le devrait.<br/>
<br/>
La curiosité, c'est aussi prendre le temps. Prendre le temps d'écouter le chant des oiseaux, sentir le vent sur sa peau et le parfum des fleurs, admirer un paysage... Nous faisons parti intégrante de la nature, apprécions-là à sa juste valeur.<br/>
Prendre le temps, alors qu'une société fait son maximum pour nous faire croire que nous ne l'avons plus&nbsp;: qui s'arrête pour écouter un artiste en pleine rue, juste comme ça, parce que ça sonne bien ? Qui prend le temps d'aider une personne en détresse ? <span style="font-style: italic;">Qui a les couilles d'aider une personne en détresse ?</span> Cette même société qui ne jure que par le travail, le travail, toujours le travail... D'ailleurs, comme aime à le rappeler <a href="http://wwz.suumitsu.eu/">Mitsu</a>&nbsp;:<br/>
<q><a href="http://fr.wiktionary.org/wiki/travail">Wiktionary, étymologie du mot "travail"</a>&nbsp;:<br/>
«&nbsp;De l’ancien français travail («&nbsp;foudre, foudroyer&nbsp;») (XIIe siècle), du bas latin (VIe siècle) tripálĭus du latin tripálĭum («&nbsp;instrument de torture à trois poutres&nbsp;»).&nbsp;»<br/>
<br/>
Donc en fait quand on travaille&nbsp;: on subit ou on fait subir au moyen d'un instrument de torture ? Dans les deux cas vous voyez l'ambiance.</q><br/>
C'est pourquoi le «&nbsp;travail&nbsp;» ne compte pas parmis mes gros cailloux. En fait, je ne travaille pas, j'exerce une activité (que j'aime, par chance) qui me rapporte de l'argent. Et cette activité, je la place dans le gravier, car elle est remplaçable, modifiable, domptable. Pas ma famille, ni mes amis.<br/>
<br/>
À cela, j'ajoute que je ne «&nbsp;travaille&nbsp;» pas <span style="font-style: italic;">pour</span> un client, mais <span style="font-weight: bold;">avec</span> un client. Différence subtile, mais qui remet les choses dans l'ordre. Ça rend encore plus esclave du travail. Vous avez une compétence, faîtes-en profiter les autres, et soyez payés en retour, rien de plus naturel. Vous n'avez pas à vous faire martyriser, ni bousiller votre vie pour des connards. Quand je vois les suicides qu'il y a eu chez Orange, je ne comprends pas pourquoi il n'y a pas eu révolte. Certes, c'est une tragédie, et j'en suis profondemment désolé pour les familles touchées. Mais se laisser atteindre par ses supérieurs et son travail à tel point que penser qu'il n'y a plus d'échappatoire ? À tout problème, il y a une solution. Si le travail avait été <span style="font-style: italic;">gravier</span> (entre autre), le futur auraient certainement pu être plus gai.<br/>
<br/>
Je suis conscient que sans activité rémunérée → pas d'argent pour vivre. Mais cette activité n'est pas tout dans votre vie. Aussi, il serait bon, peut-être, de revenir à un système de paiment plus humain (troc, service, bien matériel) ou de revoir sa façon de vivre (ou du moins s'adapter, et ne pas se laisser enfumer par la société). Mais ça, c'est un autre sujet.<br/>
<q>L'être humain perd sa santé à gagner de l'argent et par la suite, il perd son argent à se refaire la santé. Il pense au futur, au point d'oublier le présent, de sorte qu'il ne vit ni dans le présent, ni dans le futur. Finalement, il vit comme s'il n'allait jamais mourir et meurt comme s'il n'avait jamais vécu. -- <span style="font-weight: bold;">Confucius</span></q><br/>
Je vous laisse sur cette citation de Charles Bukowski&nbsp;:<br/>
<br/>
<div style="text-align:center;"><img src="media/56327f02.A_7w7A_6e2dadmay.vie.jpeg" data-original-source="http://shaarlimages.net/images/A_7w7A_6e2dadmay.vie.jpeg" alt="citation-bukowski" /></div>


