<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5001452664427688683</id><updated>2012-01-25T21:48:15.351+01:00</updated><category term='apache'/><category term='cassandra'/><category term='doodle clone'/><category term='proxy'/><category term='smtp'/><category term='optimisation'/><category term='interview question'/><category term='java'/><category term='scalability'/><category term='cluster'/><category term='php'/><category term='gentoo'/><category term='patterns'/><category term='security'/><category term='development'/><category term='maven'/><category term='tomcat'/><category term='self'/><category term='privacy'/><category term='bullshit'/><category term='algorithm'/><category term='snapshot'/><category term='presentation'/><category term='concurrent'/><category term='seo'/><category term='thumbshot'/><category term='consistency'/><category term='sql'/><category term='dns'/><category term='opensource'/><category term='wireless'/><category term='webmardi'/><category term='web 2.0'/><category term='browser'/><category term='dnssec'/><category term='ssl'/><category term='dependency'/><category term='servlet'/><category term='nosql'/><category term='epfl'/><category term='network'/><category term='fun'/><category term='md5'/><category term='j2ee'/><category term='work'/><category term='verisign'/><category term='google'/><category term='thinking'/><title type='text'>Benoit Perroud : concepts and cloud ready applications</title><subtitle type='html'>Cloud computing, web security, distributed databases, system scalability and availability, NoSQL trend, this blog tends to reduce the storm of my mind.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>96</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-734106723544108191</id><published>2011-08-05T22:48:00.005+02:00</published><updated>2011-08-08T10:03:47.282+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dependency'/><category scheme='http://www.blogger.com/atom/ns#' term='cassandra'/><category scheme='http://www.blogger.com/atom/ns#' term='servlet'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><title type='text'>Cassandra, hector, maven and tomcat</title><content type='html'>Cassandra (v0.7 and 0.8), hector (version compatible with Cassandra), maven and tomcat bound together result in a warning at tomcat startup : &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;INFO: validateJarFile(/...&amp;lt;webappspath&amp;gt;.../WEB-INF/lib/servlet-api-2.5-20081211.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class&lt;/webappspath&gt;&lt;/b&gt;&lt;/blockquote&gt;&lt;br /&gt;Nothing harmful here, but as we want to do things as clean as possible we should avoid violating Servlet Spec 2.3.&lt;br /&gt;&lt;br /&gt;So running a dependency:tree help to find out the guilty dependency :&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;[INFO] +- me.prettyprint:hector-core:jar:0.8.0-2:compile&lt;br /&gt;[INFO] |&amp;nbsp; +- org.apache.cassandra:cassandra-all:jar:0.8.1:compile&lt;br /&gt;[INFO] |&amp;nbsp; |&amp;nbsp; +- org.apache.cassandra.deps:avro:jar:1.4.0-cassandra-1:compile&lt;br /&gt;[INFO] |&amp;nbsp; |&amp;nbsp; |&amp;nbsp; \- org.mortbay.jetty:jetty:jar:6.1.22:compile&lt;br /&gt;[INFO] |&amp;nbsp; |&amp;nbsp; |&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; \- org.mortbay.jetty:servlet-api:jar:2.5-20081211:compile&lt;/blockquote&gt;&lt;br /&gt;Hum hum, &lt;b&gt;org.mortbay.jetty:servlet-api:jar:2.5-20081211&lt;/b&gt;. We found the responsible of the problem.&lt;br /&gt;&lt;br /&gt;Using &lt;i&gt;&amp;lt;dependencymanagement&amp;gt;&lt;/i&gt; in our &lt;i&gt;pom.xml&lt;/i&gt; file we will be able to mark this dependency as &lt;b&gt;provided&lt;/b&gt; and the problem should flight away :&lt;br /&gt;&lt;blockquote&gt;&amp;nbsp; &amp;lt;dependencymanagement&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dependencies&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dependency&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;groupId&amp;gt;org.mortbay.jetty&amp;lt;/groupId&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;artifactId&amp;gt;servlet-api&amp;lt;/artifactId&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;version&amp;gt;2.5-20081211&amp;lt;/version&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/dependency&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/dependencies&amp;gt;&lt;br /&gt;&amp;nbsp; &amp;lt;/dependencymanagement&amp;gt;&lt;br /&gt;&lt;/blockquote&gt;Build, deploy, and that's it !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-734106723544108191?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/734106723544108191/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=734106723544108191' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/734106723544108191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/734106723544108191'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2011/08/cassandra-hector-maven-and-tomcat.html' title='Cassandra, hector, maven and tomcat'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5590935634992654171</id><published>2011-07-16T21:38:00.003+02:00</published><updated>2011-08-04T11:18:25.823+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><category scheme='http://www.blogger.com/atom/ns#' term='verisign'/><category scheme='http://www.blogger.com/atom/ns#' term='interview question'/><title type='text'>More Interview Questions</title><content type='html'>&lt;span style="font-size: small;"&gt;All interviews are different, all candidates are different, all positions are different. The goal here is to provide some general questions to test engineering skills of candidates. These questions are common in recruiting process in technical companies like Google or Verisign.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;How could you detect a loop in a linked list ?&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It's say linked list, to be more precise you only have a pointer to the head of the list, and you know how to move to the next element of the list.&lt;br /&gt;Of course you are not allowed to modify the list at all. And obviously  you should try to propose an algorithm that do it in the most efficient way, let say you should try to target O(n).&lt;br /&gt;&lt;br /&gt;In more programmer oriented : write a function A that take as parameter the first element of a  List and return a boolean with value true if the given List has a loop, false otherwise. You know how to pass to the next element of the List : just call element.next.&lt;br /&gt;&lt;br /&gt;For those who want to try to answer by themself, stop reading here.&lt;br /&gt;&lt;br /&gt;One good  answer is to have 2 iterators that walk through the elements of the List, but at different speed. One iterator move from 1 element per iteration, the second one move from 2 elements per iteration, and check if it meet the first iterator during it's move. How fast goes the second iterator can be configurable.&lt;br /&gt;If at one point the second iterator (fast moving) meet the first one, there is a loop in the List. If the second iterator reach the end of the List, there is obviously no loop.&lt;br /&gt;&lt;br /&gt;In pseudo code, it would be :&lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;function&lt;/b&gt; A (head element of List &lt;i&gt;list&lt;/i&gt;) &lt;b&gt;return&lt;/b&gt; boolean :&lt;br /&gt;&lt;i&gt;it1&lt;/i&gt; is initialized to the head element of &lt;i&gt;list&lt;/i&gt;&lt;br /&gt;&lt;i&gt;it2&lt;/i&gt; is initialized to the head element of &lt;i&gt;list&lt;/i&gt;&lt;br /&gt;&lt;b&gt;while&lt;/b&gt; &lt;i&gt;it2&lt;/i&gt; has not reach end &lt;i&gt; list&lt;/i&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;for&lt;/b&gt; number of element &lt;i&gt;it2&lt;/i&gt; will move&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; it2 move to the next element.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;b&gt;if&lt;/b&gt; the element of &lt;i&gt;it2&lt;/i&gt; is equal to the element of &lt;i&gt;it1&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; there is a loop ! return &lt;b&gt;true&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;i&gt;it1&lt;/i&gt; move to the next element&lt;br /&gt;there is no loop. return &lt;b&gt;false&lt;/b&gt;&lt;/blockquote&gt;As targeted, this algorithm will be on complexity of O(n), as the worst case is the last element looping to itself. When the last element loop to the first one, the algorithm will detect the loop in n / speed of the second iterator.&lt;br /&gt;And finally, the memory footprint is  very low.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;What are the advantages of a LinkedList over an ArrayList ?&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This  question is more often ask in a different way : what are the &lt;b&gt;differences&lt;/b&gt; between a &lt;i&gt;LinkedList&lt;/i&gt; and an &lt;i&gt;ArrayList&lt;/i&gt;. But turning the question up side down like here is a bit more interesting. So what are the &lt;b&gt;advantages&lt;/b&gt; ?&lt;br /&gt;&lt;br /&gt;The basic advantage of the &lt;i&gt;LinkedList&lt;/i&gt; is its O(1) insertion and deletion complexity for &lt;b&gt;any&lt;/b&gt; given element, while &lt;i&gt;ArrayList&lt;/i&gt; need to move back or forth the elements after the given element. Another advantage is the  linearly increasing  memory footprint of a &lt;i&gt;LinkedList&lt;/i&gt;, when &lt;i&gt;ArrayList&lt;/i&gt; memory (still linear but) increases by steps, and then perform sometimes costly memory copies. With such memory copies &lt;i&gt;ArrayList&lt;/i&gt; have an&lt;i&gt; amotized complexity in O(1)&lt;/i&gt;, but this leads to non deterministic operations, which are unwanted when dealing with tight SLAs.&lt;br /&gt;One more hidden advantage of the &lt;i&gt;LindekList&lt;/i&gt; is still in the topic of memory usage : it does not require to allocate blocks of memory, elements stored in &lt;i&gt;LinkedList&lt;/i&gt; do not require to be allocated in contiguous memory. Just notice that  fragmentation of  the memory is not always seen as good point.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5590935634992654171?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5590935634992654171/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5590935634992654171' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5590935634992654171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5590935634992654171'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2011/07/more-interview-questions.html' title='More Interview Questions'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-8976806790282722602</id><published>2011-03-07T14:32:00.001+01:00</published><updated>2011-07-06T16:02:15.877+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webmardi'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><title type='text'>NoSQL Overview @Webmardi</title><content type='html'>Tuesday 1st of March 2011 I gave an overview of NoSQL at the &lt;a href="http://www.webmardi.ch/"&gt;Webmardi&lt;/a&gt; monthly event. The presentation was hosted by Webdoc. Thanks all for the warm welcome !&lt;br /&gt;&lt;br /&gt;Some pictures :&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-Ag3kvCSEe6M/TXTdUpMCnpI/AAAAAAAAAMw/B2ILMKuT4to/s1600/0d9504ab53284a72966f8ff06012411d_7.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://lh5.googleusercontent.com/-Ag3kvCSEe6M/TXTdUpMCnpI/AAAAAAAAAMw/B2ILMKuT4to/s320/0d9504ab53284a72966f8ff06012411d_7.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-G50HEjpisj8/TXTdYD7kMeI/AAAAAAAAAM0/PtiT_vMjEDk/s1600/tc8hy.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="239" src="https://lh5.googleusercontent.com/-G50HEjpisj8/TXTdYD7kMeI/AAAAAAAAAM0/PtiT_vMjEDk/s320/tc8hy.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The slides are available on Slideshare : &lt;a href="http://www.slideshare.net/benoitperroud/nosql-overview-implementation-free"&gt;NoSQL Overview, implementation free&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It is called "Implementation free" because I didn't want to focus on a particular implementation of a NoSQL datasore, but rather generalize concepts of "What is NoSQL". And it's a tricky answer to formulate :)&lt;br /&gt;&lt;br /&gt;So what is NoSQL ? It's a family of datastores that does not have SQL as main data access pattern.&lt;br /&gt;&lt;br /&gt;The presentation was hosted by Webdoc :&amp;nbsp;&lt;a href="http://www.webdoc.com/"&gt;http://www.webdoc.com&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-8976806790282722602?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/8976806790282722602/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=8976806790282722602' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8976806790282722602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8976806790282722602'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2011/03/nosql-overview-webmardi.html' title='NoSQL Overview @Webmardi'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-Ag3kvCSEe6M/TXTdUpMCnpI/AAAAAAAAAMw/B2ILMKuT4to/s72-c/0d9504ab53284a72966f8ff06012411d_7.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-444877559751254594</id><published>2011-01-06T12:40:00.006+01:00</published><updated>2011-01-06T13:33:38.595+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='consistency'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><category scheme='http://www.blogger.com/atom/ns#' term='scalability'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrent'/><title type='text'>Eventually Consistency demystified</title><content type='html'>In my crusade into the NoSQL world, &lt;a href="http://en.wikipedia.org/wiki/Eventual_consistency"&gt;&lt;span style="font-style: italic;"&gt;Eventually Consistency&lt;/span&gt;&lt;/a&gt; is everywhere. I want to demystify this property a little bit here.&lt;br /&gt;&lt;br /&gt;But let's begin with an example to have the same base for the  discussion :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Let "Node1", "Node2" and "Node3" be three nodes (servers) that are part of our distributed datastore.&lt;/li&gt;&lt;li&gt;Let "User A", "User B", "User c" be three users wanting to read and write data in our fictive distributed datastore.&lt;/li&gt;&lt;/ul&gt;At time (1), "User A" write the value "A" to "Node1". "Node1" will replicate asynchronously this value to both "Node2" and "Node3" (specific to my example).&lt;br /&gt;At time (2) the write call of "Node A" returns. But the replication of value "A" hasn't been completely propagate to "Node2" and "Node3".&lt;br /&gt;At time (3), "User B" and "User C" will read value "A" from "Node1" and "Node2" respectively. "User B" got the latest value (because it reads the node which initiate the update), "User C" will read  either the old or the new version of "A",  but without any  guarantee regarding what it will read.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_9jdtZI7diwk/TSWrrYijUlI/AAAAAAAAAMc/_uiBCZg_slU/s1600/Eventually_consistency_read.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 334px;" src="http://4.bp.blogspot.com/_9jdtZI7diwk/TSWrrYijUlI/AAAAAAAAAMc/_uiBCZg_slU/s400/Eventually_consistency_read.png" alt="" id="BLOGGER_PHOTO_ID_5559038076868842066" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In a future time (5), "User B" and "User C" re-read value "A" and then got the same value. At this point of time, the datastore is consistent.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Immediate Consistency&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In a &lt;a href="http://en.wikipedia.org/wiki/Immediate_consistency"&gt;&lt;span style="font-style: italic;"&gt;Immediate Consistency&lt;/span&gt;&lt;/a&gt;, opposing &lt;span style="font-style: italic;"&gt;Eventually Consistency&lt;/span&gt;, the write call from "User A" should wait till the replication is done on other nodes before returning, and replica nodes ("Node2" and "Node3") should be synchronized to expose the new value at the same time.&lt;br /&gt;&lt;br /&gt;Moreover, if "Node1" is unable to talk to "Node2", the write replication will probably fail then the write call from "User A" will fail.&lt;br /&gt;&lt;br /&gt;As we can notice, &lt;span style="font-style: italic;"&gt;Immediate Consistency&lt;/span&gt;  is hard to scale (see &lt;a href="http://en.wikipedia.org/wiki/Two-phase_commit_protocol"&gt;two-phase commit&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Paxos_algorithm"&gt;paxos algorithm&lt;/a&gt;), because it increases the latency of the writes and makes the system not redundant to failure.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Trade-off for scaling writes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Eventually Consistency&lt;/span&gt; is then a  trade-off for scaling writes that seems reasonable in certain use-cases.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-444877559751254594?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/444877559751254594/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=444877559751254594' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/444877559751254594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/444877559751254594'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2011/01/eventually-consistency-demystified.html' title='Eventually Consistency demystified'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_9jdtZI7diwk/TSWrrYijUlI/AAAAAAAAAMc/_uiBCZg_slU/s72-c/Eventually_consistency_read.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-345770704783454126</id><published>2010-12-23T10:38:00.004+01:00</published><updated>2010-12-23T11:21:38.196+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dns'/><category scheme='http://www.blogger.com/atom/ns#' term='dnssec'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><title type='text'>DNSSEC NSEC3 domain hash computation algorithm</title><content type='html'>DNSSEC is a DNS extension in order to authenticate  and ensure integrity of DNS responses, in order to offers protection against DNS spoofing.&lt;br /&gt;&lt;br /&gt;DNSSEC comes with two "denial of existence" mechanism : NSEC (RFCs 4033, 4034, 4035) and NSEC3 (RFC 5155).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Now how "denial of existence" works ?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When a query is performed on a non-existing domain, a specific answer is returned to the resolution client, given the closest  domains that are alphabetically before and after the queried domain. But what is very sensible in this way of proving the non-existence of a domain is that we can easily enumerate the whole zone.&lt;br /&gt;&lt;br /&gt;That's why NSEC3 was designed to prove the non-existence of a domain, but in the same time to avoid the zone walk through.&lt;br /&gt;Instead of simply returning the closest domains, it returns a hash of the domains.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;How to compute NSEC3 Hash ?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I will detail a little bit how this NSESC3 hash is computed :&lt;br /&gt;&lt;br /&gt;I you have a look at a zone, you will find additional records, like &lt;span style="font-style: italic;"&gt;NSEC3PARAM&lt;/span&gt; :&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;example.com. NSEC3PARAM 1 0 12 aabbccdd&lt;/blockquote&gt;The format of such record is composed of :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;an algorithm field. 1 means SHA1&lt;/li&gt;&lt;li&gt;a flags field&lt;/li&gt;&lt;li&gt;an iterations field&lt;/li&gt;&lt;li&gt;a salt, represented as a sequence of case-insensitive &lt;span style="font-weight: bold;"&gt;hexadecimal digits&lt;/span&gt;.&lt;/li&gt;&lt;/ul&gt;Then the hashing algorithm is given by :&lt;br /&gt;&lt;pre class="newpage"&gt; IH(salt, x, 0) = H(x || salt), and&lt;br /&gt;IH(salt, x, k) = H(IH(salt, x, k-1) || salt), if k &gt; 0&lt;br /&gt;&lt;/pre&gt;With my &lt;span style="font-style: italic;"&gt;example.com&lt;/span&gt; domain, the hash algorithm will be :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;IH(fromHexStringToByte("aabbccdd"), toCanonicalWireFormat("example.com"), 12)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;fromHexStringToByte&lt;/span&gt; is a base 16 decoder : &lt;span style="font-style: italic;"&gt;fromHexStringToByte("aabbccdd") = [0xaa, 0xbb, 0xcc, 0xdd]&lt;/span&gt;. See &lt;a href="https://tools.ietf.org/html/rfc4648"&gt;RFC4648&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;toCanonicalWireFormat&lt;/span&gt; convert the domain in wire format using its canonical form : &lt;span style="font-style: italic;"&gt;toCanonicalWireFormat("example.com") = [0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00]&lt;/span&gt;. See &lt;a href="https://tools.ietf.org/html/rfc4034#section-6.2"&gt;RFC4034&lt;/a&gt; (canonical form), &lt;a href="https://tools.ietf.org/html/rfc3845#section-2.3"&gt;RFC3845&lt;/a&gt; (wire format)&lt;br /&gt;&lt;br /&gt;And that's it, you are now able to compute the NSEC3 hash of your favourite domain. You just need to wait for NSEC3PARAM to be published in the respective zone to got all the necessary parameters :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-345770704783454126?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/345770704783454126/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=345770704783454126' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/345770704783454126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/345770704783454126'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2010/12/dnssec-nsec3-domain-hash-computation.html' title='DNSSEC NSEC3 domain hash computation algorithm'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-887629624219599225</id><published>2010-11-19T14:19:00.004+01:00</published><updated>2010-11-19T14:28:53.890+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>Using java.net.InetAddress.getByName() to validate an IP Address may be too permissive</title><content type='html'>&lt;span style="font-style: italic;"&gt;java.net.InetAddress.getByName()&lt;/span&gt; static function can be used for validating a given IP Address.&lt;br /&gt;&lt;br /&gt;But doing that way you need to pay attention to certain side effects border values :&lt;br /&gt;&lt;pre&gt;String ip = "1.2.3.4"; // valid IP Address&lt;br /&gt;InetAddress address = InetAddress.getByName( ip );&lt;br /&gt;Assert.assertEquals( ip, address.getHostAddress() ); // Pass. OK&lt;br /&gt;&lt;br /&gt;String ip = "1.2.3"; // invalid IP Address&lt;br /&gt;InetAddress address = InetAddress.getByName( ip );&lt;br /&gt;Assert.assertEquals( ip, address.getHostAddress() ); // Pass. &lt;span style="font-weight: bold;"&gt;KO&lt;/span&gt; !&lt;/pre&gt;If you have a look a little  deeper, you will see that &lt;span style="font-style: italic;"&gt;1.2.3&lt;/span&gt; is transformed in &lt;span style="font-style: italic;"&gt;1.2.0.3&lt;/span&gt;, which after transformation become a valid IP Address.&lt;br /&gt;&lt;br /&gt;Having that in mind, a IP Address validation function can look like :&lt;br /&gt;&lt;pre&gt;public static boolean validateIpAddress( String anIpAddress ) {&lt;br /&gt; try {&lt;br /&gt;  InetAddress address = InetAddress.getByName( anIpAddress );&lt;br /&gt;  return address.getHostAddress().equals( anIpAddress );&lt;br /&gt; } catch (final UnknownHostException e) {&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-887629624219599225?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/887629624219599225/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=887629624219599225' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/887629624219599225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/887629624219599225'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2010/11/using-javanetinetaddressgetbyname-to.html' title='Using java.net.InetAddress.getByName() to validate an IP Address may be too permissive'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-8776224348796041777</id><published>2010-10-09T13:46:00.003+02:00</published><updated>2010-10-09T14:16:15.889+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dns'/><category scheme='http://www.blogger.com/atom/ns#' term='work'/><category scheme='http://www.blogger.com/atom/ns#' term='verisign'/><title type='text'>Moving from ELCA to Verisign</title><content type='html'>I had a great time at &lt;a href="http://www.elca.ch"&gt;ELCA Informatique SA&lt;/a&gt;, working for almost 3 years on &lt;a href="http://www.secutix.com"&gt;Secutix, a complete ticketing system&lt;/a&gt;. But now it's time for me to move forward and see something else : different projects, different colleagues, different cultures, speak more English, nearer from home, and so on...&lt;br /&gt;&lt;br /&gt;That's why I will move to &lt;a href="http://www.verisign.com"&gt;Verisign&lt;/a&gt;, beginning the 2nd of November (the 1st is day off :)). Working on the heart of Internet (aka &lt;a href="http://en.wikipedia.org/wiki/Domain_Name_System"&gt;DNS&lt;/a&gt;) is some kind of child's dream which I will be able to realize ! I'm really excited to see how &lt;a href="http://en.wikipedia.org/wiki/Root_nameserver"&gt;root name servers&lt;/a&gt; work, what's behind &lt;a href="http://en.wikipedia.org/wiki/Domain_name_registrar"&gt;Registrars&lt;/a&gt; (aka &lt;a href="http://en.wikipedia.org/wiki/Domain_name_registry"&gt;registry&lt;/a&gt;), implementing &lt;a href="http://en.wikipedia.org/wiki/Dnssec"&gt;DNSSEC&lt;/a&gt; or what means 1 billion transactions a day.&lt;br /&gt;&lt;br /&gt;I really look forward to start there, and in the same time wish all the best to the Secutix team !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-8776224348796041777?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/8776224348796041777/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=8776224348796041777' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8776224348796041777'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8776224348796041777'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2010/10/moving-from-elca-to-verisign.html' title='Moving from ELCA to Verisign'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2225593076371054313</id><published>2010-08-02T11:19:00.004+02:00</published><updated>2010-08-03T11:35:08.848+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ssl'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Dealing with old SSL certificats (algorithm check failed: MD2withRSA is disabled)</title><content type='html'>I faced the problem of &lt;span style="font-style: italic;"&gt;SSLHandShakeException&lt;/span&gt;, or "algorithm check failed: &lt;span style="font-style: italic;"&gt;MD2withRSA&lt;/span&gt; is disabled" when upgrading above java 1.6.0_17.&lt;br /&gt;&lt;br /&gt;The source of problem is well known, the &lt;span style="font-style: italic;"&gt;MD2withRSA&lt;/span&gt; has been removed from the JVM because it is no more secure (References : &lt;span id="summary_alias_container"&gt;&lt;span id="short_desc_nonedit_display"&gt;&lt;a href="https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2009-2409"&gt;CVE-2009-2409 deprecate MD2 in SSL cert validation&lt;/a&gt;, &lt;a href="http://www.oracle.com/technetwork/java/javase/index-140291.html"&gt;Sun java 1.6u17 release notes&lt;/a&gt;)&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Lot of posts around the problem give the solution to update the certificate to use another signature algorithm, for example &lt;span style="font-style: italic;"&gt;SHA1withRSA&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;But what to do when the certificate is not under our hands ?&lt;br /&gt;&lt;br /&gt;I will try to explain the problem and how I solved it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Analyse the certificate's chain&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First of all is to analyse the chain of certificate to see which one is using the deprecated algorithm.&lt;br /&gt;&lt;br /&gt;The following command will print all the certificates in the chain and store them under the names level0.pem, level1.pem and so on.&lt;br /&gt;&lt;blockquote  style="font-family:courier new;"&gt;&lt;span style="font-weight: bold;"&gt;openssl&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;s_client&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;-showcerts&lt;/span&gt; -connect xxxxxxxxxxxxxxxxx:443 &lt; /dev/null | awk -v c=-1 '/-----BEGIN CERTIFICATE-----/{inc=1;c++} inc {print &gt; ("level" c ".pem")}/---END CERTIFICATE-----/{inc=0}'; for i in level?.pem; do &lt;span style="font-weight: bold;"&gt;openssl x509&lt;/span&gt; -noout -serial -subject -issuer -in "$i"; done&lt;/blockquote&gt;The output given in my case :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Cert1, serial=xxxxxxxxxxxxxxxxxxxxx&lt;/span&gt;&lt;br /&gt;subject= xxxxxxxxxxxxxxxxxxxxxxxx&lt;br /&gt;issuer= /C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Cert2, serial=30000002&lt;/span&gt;&lt;br /&gt;subject= /C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA&lt;br /&gt;issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Cert3, serial=70BAE41D10D92934B638CA7B03CCBABF&lt;/span&gt;&lt;br /&gt;subject= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority&lt;br /&gt;issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;We have a chain of 3 certificates, Cert1 signed by Cert2 signed by Cert3 signed by Cert3 (selfsigned).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Note : the first error here is that the webserver gives explicitly the entire chain of certificates. Thus the change of any root certificate provided by the jre will not be taken into account automatically.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Digging into the details of the third certificate (&lt;span style="font-weight: bold;"&gt;openssl x509&lt;/span&gt; -in level2.pem &lt;span style="font-weight: bold;"&gt;-text&lt;/span&gt;) show that this certificate is signed with the old algorithm :&lt;br /&gt;&lt;blockquote&gt;Certificate:&lt;br /&gt;Data:&lt;br /&gt;    Version: 1 (0x0)&lt;br /&gt;    Serial Number:&lt;br /&gt;        70:ba:e4:1d:10:d9:29:34:b6:38:ca:7b:03:cc:ba:bf&lt;br /&gt;    &lt;span style="font-weight: bold;"&gt;Signature Algorithm: md2WithRSAEncryption&lt;/span&gt;&lt;br /&gt;    Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority&lt;br /&gt;    Validity&lt;br /&gt;        Not Before: Jan 29 00:00:00 1996 GMT&lt;br /&gt;        Not After : Aug  1 23:59:59 2028 GMT&lt;/blockquote&gt;So not only the way of providing the full chain is wrong in point of view of the server configuration, but the last certificate was never updated and thus still use the deprecated signature algorigthm.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Correct the certificate's chain&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now we have identified the weak link of the chain, what's the next step ?&lt;br /&gt;&lt;br /&gt;The key point here is to correct the certificate's chain in order to make it more compliant to the standards :&lt;br /&gt;&lt;br /&gt;As the third certificate is a well know root certificate (&lt;span style="font-style: italic;"&gt;named &lt;/span&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;verisignclass3ca&lt;/span&gt;&lt;span style="font-style: italic;"&gt; in the jre cacerts&lt;/span&gt;), a working version of it is provided in the cacert of java sun (&lt;span style="font-style: italic;"&gt;debian oriented commande line, with "changeit" as password&lt;/span&gt;) :&lt;br /&gt;&lt;blockquote  style="font-family:courier new;"&gt;&lt;span style="font-weight: bold;"&gt;keytool -keystore&lt;/span&gt; /etc/java-6-sun/security/cacerts -exportcert -alias "verisignclass3ca" | &lt;span style="font-weight: bold;"&gt;openssl x509 -inform der -text&lt;/span&gt;&lt;/blockquote&gt;will output :&lt;br /&gt;&lt;blockquote&gt;Certificate:&lt;br /&gt;Data:&lt;br /&gt;    Version: 1 (0x0)&lt;br /&gt;    Serial Number:&lt;br /&gt;        3c:91:31:cb:1f:f6:d0:1b:0e:9a:b8:d0:44:bf:12:be&lt;br /&gt;    &lt;span style="font-weight: bold;"&gt;Signature Algorithm: sha1WithRSAEncryption&lt;/span&gt;&lt;br /&gt;    Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority&lt;br /&gt;    Validity&lt;br /&gt;        Not Before: Jan 29 00:00:00 1996 GMT&lt;br /&gt;        Not After : Aug  2 23:59:59 2028 GMT&lt;/blockquote&gt;which is the same as before, but with &lt;span style="font-style: italic;"&gt;sha1WithRSAEncryption&lt;/span&gt; instead of &lt;span style="font-style: italic;"&gt;md2WithRSAEncryption&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Thus we can simply remove it from the chain and validate normally the certificate's chain &lt;span style="font-weight: bold;"&gt;with only Cert1 and Cert2&lt;/span&gt;. The validation from Cert2 to "verisignclass3ca" will be automagically done.&lt;br /&gt;&lt;br /&gt;To be able to do this, we need to create a custom &lt;span style="font-style: italic;"&gt;X509TrustManager&lt;/span&gt; which will behave the following :&lt;br /&gt;&lt;ol&gt;&lt;li&gt;if the certificate's serial is the one of Cert1 (serial=xxxxxxxxxxxxxxxxxxxxx), then &lt;span style="font-weight: bold;"&gt;remove the last certificate of the chain and revalidate&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;In all other cases, validate normally the certificate's chain.&lt;/li&gt;&lt;/ol&gt;Thus the custom &lt;span style="font-style: italic;"&gt;X509TrustManager &lt;/span&gt;act as delegate, with one little variation (&lt;span style="font-style: italic;"&gt;note : if someone know a easier way to instantiate the default &lt;/span&gt;&lt;span style="font-style: italic;"&gt;TrustManagerFactory&lt;/span&gt;&lt;span style="font-style: italic;"&gt; of &lt;/span&gt;&lt;span style="font-style: italic;"&gt;TrustManager&lt;/span&gt;&lt;span style="font-style: italic;"&gt;, please leave me a comment&lt;/span&gt;). Refer to my article about &lt;a href="http://benoitperroud.blogspot.com/2010/08/java-and-certificates-mess-blind-ssl.html"&gt;blind SSL factory for httpClients&lt;/a&gt; to see how to pass a custom &lt;span style="font-style: italic;"&gt;TrustManager&lt;/span&gt; to a SSL factory.&lt;br /&gt;&lt;br /&gt;My custom &lt;span style="font-style: italic;"&gt;X509TrustManager&lt;/span&gt; class will finally look as the follow :&lt;br /&gt;&lt;pre&gt;public class CustomX509TrustManager implements X509TrustManager {&lt;br /&gt;&lt;br /&gt;   X509TrustManager delegate = null;&lt;br /&gt;&lt;br /&gt;   public CustomX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException, CertificateException {&lt;br /&gt;    // Instantiate the default X509TrustManager&lt;br /&gt;    TrustManagerFactory factory = TrustManagerFactory&lt;br /&gt;           .getInstance(TrustManagerFactory.getDefaultAlgorithm());&lt;br /&gt;       factory.init(keystore);&lt;br /&gt;       TrustManager[] trustManagers = factory.getTrustManagers();&lt;br /&gt;       if (trustManagers != null &amp;amp;&amp;amp; trustManagers.length &gt; 0) {&lt;br /&gt;           for (int i = 0; i &lt; trustManagers.length; i++) {&lt;br /&gt;               TrustManager trustManager = factory.getTrustManagers()[i];&lt;br /&gt;               if (trustManager instanceof X509TrustManager) {&lt;br /&gt;                   delegate = (X509TrustManager) trustManager;&lt;br /&gt;                   break;&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;       if (delegate == null) {&lt;br /&gt;           throw new CertificateException("Cannot found any instance of X509TrustManager");&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public X509Certificate[] getAcceptedIssuers() {&lt;br /&gt;    if (delegate == null) {&lt;br /&gt;        return null;&lt;br /&gt;    } else {&lt;br /&gt;        return delegate.getAcceptedIssuers();&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void checkClientTrusted(final X509Certificate[] c, final String a)&lt;br /&gt;                   throws CertificateException {&lt;br /&gt;       if (delegate != null) {&lt;br /&gt;        delegate.checkClientTrusted(c, a);&lt;br /&gt;       } else {&lt;br /&gt;        throw new CertificateException("Unable to validate this certificate (delegate is null).");&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public void checkServerTrusted(final X509Certificate[] c, final String a)&lt;br /&gt;                   throws CertificateException {&lt;br /&gt;    if (delegate != null) {&lt;br /&gt;           // hardcoding test to be sure we are trying to validate the right certificate&lt;br /&gt;           if (c.length == 3 &amp;amp;&amp;amp; c[0].getSerialNumber().toString(16).equals(BADCERTIFICATESIGNATURE)) {&lt;br /&gt;            c = new X509Certificate[] {c[0], c[1]};&lt;br /&gt;           }&lt;br /&gt;           delegate.checkServerTrusted(c, a);&lt;br /&gt;    } else {&lt;br /&gt;        throw new CertificateException("Unable to validate this certificate (delegate is null).");&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   private static final String BADCERTIFICATESIGNATURE = "xxxxxxxxxxxxxxxxxxxx";&lt;br /&gt;}&lt;/pre&gt;With this implementation I'm sure that the my invalid certificate will continue to work, and it cannot be faked (as it could be with a completely blind TrustManager). But I can also expect that when the provider will update its certificate, everything will continue to work as expected because all other certificates are still validate the regular way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2225593076371054313?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2225593076371054313/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2225593076371054313' title='7 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2225593076371054313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2225593076371054313'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2010/08/dealing-with-old-ssl-certificats.html' title='Dealing with old SSL certificats (algorithm check failed: MD2withRSA is disabled)'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2424164447573821741</id><published>2010-08-02T08:53:00.003+02:00</published><updated>2010-08-10T12:33:45.580+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='ssl'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Java and certificate's mess : blind SSL factory for commons httpClient</title><content type='html'>There are parts of Java which are not very "quick development" oriented. The side I want to illustrate here is dealing with SSL.&lt;br /&gt;&lt;br /&gt;When the application is in early development stage, we don't want to bother with stuff like valid certificate. We don't want to get stuck for days because we haven't received valid development SSL certificate from Verisign or other "&lt;span style="font-style: italic;"&gt;more trusted than me&lt;/span&gt;" monopoles. We  just want to activate the "&lt;span style="font-style: italic;"&gt;--no-check-certificate&lt;/span&gt;" à la &lt;span style="font-style: italic;"&gt;wget&lt;/span&gt;, or "&lt;span style="font-style: italic;"&gt;CURLOPT_SSL_VERIFYPEER&lt;/span&gt;" à la &lt;span style="font-style: italic;"&gt;PHP&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Adding a new certificate in the cacert file is not so complicated, but it is not always possible on every computers (should developers have administrators rights on their computers ?), or break the debian pakage integrity and risk to be overridden at the next &lt;span style="font-style: italic;"&gt;JRE&lt;/span&gt; update.&lt;br /&gt;&lt;br /&gt;No, for development phase, a &lt;span style="font-weight: bold;"&gt;blind SSL factory&lt;/span&gt; is a good point for productivity. Simply &lt;span style="font-weight: bold;"&gt;DO NOT FORGET TO REMOVE IT&lt;/span&gt; in the integration or pre-production phase. Having valid and trusted SSL certificate in production is NOT an optional thing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;What is a blind SSL factory&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A blind SSL factory is simply an SSL factory which will validate any certificate. Expirated, selfsigned, but also man-in-the-middled or forged certificates will be trusted.&lt;br /&gt;&lt;br /&gt;Mike McKinney already explained &lt;a href="http://blog.platinumsolutions.com/node/79"&gt;how to create a blind SSL factory for LDAP connexions&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I will leverage his explanations to enable blind SSL factory for &lt;a href="http://hc.apache.org/"&gt;commons httpClient&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The start point is to create a &lt;span style="font-style: italic;"&gt;TrustManager&lt;/span&gt; which will trust any certificate, and then give this &lt;span style="font-style: italic;"&gt;TrustManager&lt;/span&gt; to the SSL factory. This will result in a blind SSL factory :)&lt;br /&gt;&lt;br /&gt;Anonymous class that implements &lt;span style="font-style: italic;"&gt;X509TrustManager&lt;/span&gt; :&lt;br /&gt;&lt;pre&gt;class BlindX509TrustManager implements X509TrustManager&lt;br /&gt;{&lt;br /&gt;   public X509Certificate[] getAcceptedIssuers()&lt;br /&gt;   {&lt;br /&gt;       return null;&lt;br /&gt;   }&lt;br /&gt;   public void checkClientTrusted(final X509Certificate[] c, final String a)&lt;br /&gt;   {&lt;br /&gt;   }&lt;br /&gt;   public void checkServerTrusted(final X509Certificate[] c, final String a)&lt;br /&gt;   {&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;Initializing the &lt;span style="font-style: italic;"&gt;SSLContext&lt;/span&gt; to retrieve a &lt;span style="font-style: italic;"&gt;SocketFactory&lt;/span&gt; :&lt;br /&gt;&lt;pre&gt;SSLContext sc = SSLContext.getInstance("SSL");&lt;br /&gt;sc.init(null, new TrustManager[] { new BlindX509TrustManager() }, new java.security.SecureRandom());&lt;br /&gt;SocketFactory blindFactory = sc.getSocketFactory();&lt;br /&gt;&lt;/pre&gt;And finally the &lt;span style="font-style: italic;"&gt;BlindSSLProtocolSocketFactory&lt;/span&gt; which implements the needed &lt;span style="font-style: italic; font-weight: bold;"&gt;ProtocolSocketFactory&lt;/span&gt; of &lt;span style="font-style: italic;"&gt;httpClient&lt;/span&gt; :&lt;br /&gt;&lt;pre&gt;public class BlindSSLProtocolSocketFactory implements SecureProtocolSocketFactory&lt;br /&gt;{&lt;br /&gt;   public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException,&lt;br /&gt;       UnknownHostException&lt;br /&gt;   {&lt;br /&gt;       return blindFactory.createSocket(host, port, clientHost, clientPort);&lt;br /&gt;   }&lt;br /&gt;   public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params)&lt;br /&gt;       throws IOException, UnknownHostException, ConnectTimeoutException&lt;br /&gt;   {&lt;br /&gt;       if (params == null)&lt;br /&gt;       {&lt;br /&gt;           throw new IllegalArgumentException("Parameters may not be null");&lt;br /&gt;       }&lt;br /&gt;       int timeout = params.getConnectionTimeout();&lt;br /&gt;       if (timeout == 0)&lt;br /&gt;       {&lt;br /&gt;           return createSocket(host, port, localAddress, localPort);&lt;br /&gt;       }&lt;br /&gt;       else&lt;br /&gt;       {&lt;br /&gt;           return ControllerThreadSocketFactory.createSocket(this, host, port, localAddress, localPort, timeout);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;   public Socket createSocket(String host, int port) throws IOException, UnknownHostException&lt;br /&gt;   {&lt;br /&gt;       return blindFactory.createSocket(host, port);&lt;br /&gt;   }&lt;br /&gt;   public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException&lt;br /&gt;   {&lt;br /&gt;       return ((SSLSocketFactory) blindFactory).createSocket(socket, host, port, autoClose);&lt;br /&gt;   }&lt;br /&gt;   public boolean equals(Object obj)&lt;br /&gt;   {&lt;br /&gt;       return obj != null &amp;amp;&amp;amp; obj.getClass().equals(getClass());&lt;br /&gt;   }&lt;br /&gt;   public int hashCode()&lt;br /&gt;   {&lt;br /&gt;       return getClass().hashCode();&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;Everything tied up together, put into the classpath of the application, will override the https protocol with the &lt;span style="font-style: italic;"&gt;BlindSSLProtocolSocketFactory&lt;/span&gt; and thus allow your code to connect any certificate !&lt;br /&gt;&lt;pre&gt;public class BlindSSLProtocolSocketFactory implements SecureProtocolSocketFactory&lt;br /&gt;{&lt;br /&gt; private static final Log LOG = LogFactory.getLog(BlindSSLProtocolSocketFactory.class);&lt;br /&gt; public BlindSSLProtocolSocketFactory()&lt;br /&gt; {&lt;br /&gt;     blindFactory = createBlindSocketFactory();&lt;br /&gt; }&lt;br /&gt; public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException,&lt;br /&gt;         UnknownHostException&lt;br /&gt; {&lt;br /&gt;     return blindFactory.createSocket(host, port, clientHost, clientPort);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params)&lt;br /&gt;         throws IOException, UnknownHostException, ConnectTimeoutException&lt;br /&gt; {&lt;br /&gt;     if (params == null)&lt;br /&gt;     {&lt;br /&gt;         throw new IllegalArgumentException("Parameters may not be null");&lt;br /&gt;     }&lt;br /&gt;     int timeout = params.getConnectionTimeout();&lt;br /&gt;     if (timeout == 0)&lt;br /&gt;     {&lt;br /&gt;         return createSocket(host, port, localAddress, localPort);&lt;br /&gt;     }&lt;br /&gt;     else&lt;br /&gt;     {&lt;br /&gt;         return ControllerThreadSocketFactory.createSocket(this, host, port, localAddress, localPort, timeout);&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt; public Socket createSocket(String host, int port) throws IOException, UnknownHostException&lt;br /&gt; {&lt;br /&gt;     return blindFactory.createSocket(host, port);&lt;br /&gt; }&lt;br /&gt; public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException&lt;br /&gt; {&lt;br /&gt;     return ((SSLSocketFactory) blindFactory).createSocket(socket, host, port, autoClose);&lt;br /&gt; }&lt;br /&gt; public boolean equals(Object obj)&lt;br /&gt; {&lt;br /&gt;     return obj != null &amp;amp;&amp;amp; obj.getClass().equals(getClass());&lt;br /&gt; }&lt;br /&gt; public int hashCode()&lt;br /&gt; {&lt;br /&gt;     return getClass().hashCode();&lt;br /&gt; }&lt;br /&gt; private SocketFactory blindFactory = null;&lt;br /&gt; private static SocketFactory createBlindSocketFactory()&lt;br /&gt; {&lt;br /&gt;     try&lt;br /&gt;     {&lt;br /&gt;         SSLContext context = SSLContext.getInstance("SSL");&lt;br /&gt;         context.init(null, new TrustManager[] { new BlindX509TrustManager() }, null);&lt;br /&gt;         return context.getSocketFactory();&lt;br /&gt;     }&lt;br /&gt;     catch (Exception e)&lt;br /&gt;     {&lt;br /&gt;         LOG.error(e.getMessage(), e);&lt;br /&gt;         throw new HttpClientError(e.toString());&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;And to regirster the new protocol as the default https protocol :&lt;br /&gt;&lt;pre style="font-weight: bold;"&gt;Protocol.registerProtocol("https", new Protocol("https", (ProtocolSocketFactory) new BlindSSLProtocolSocketFactory(), 443));&lt;/pre&gt;&lt;br /&gt;Please note that if you want only access a selfsigned certificate you have better to use &lt;a href="http://svn.apache.org/viewvc/httpcomponents/oac.hc3x/trunk/src/contrib/org/apache/commons/httpclient/contrib/ssl/EasySSLProtocolSocketFactory.java"&gt;&lt;span style="font-style: italic;"&gt;EasySSLProtocolSocketFactory&lt;/span&gt;&lt;/a&gt; from &lt;span style="font-style: italic;"&gt;httpClient contibs&lt;/span&gt;. It still validate the selfsigned certificate, so expired or bad certificate will be denied.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2424164447573821741?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2424164447573821741/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2424164447573821741' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2424164447573821741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2424164447573821741'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2010/08/java-and-certificates-mess-blind-ssl.html' title='Java and certificate&apos;s mess : blind SSL factory for commons httpClient'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2383658379882692325</id><published>2010-04-25T10:30:00.001+02:00</published><updated>2010-04-25T10:44:26.203+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='doodle clone'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrent'/><title type='text'>Implementing unique constraints with Cassandra</title><content type='html'>I was talking about my "&lt;a href="http://doodle.noisette.ch/"&gt;Doodle clone with Cassandra backend&lt;/a&gt;" in a &lt;a href="http://benoitperroud.blogspot.com/2010/04/doodle-clone-with-cassandra-backend.html"&gt;previous post&lt;/a&gt;, I want to explain a little bit how I implement 2 kinds of constraints with Cassandra.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Unique name constrain&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When subscribing to a poll, a unique constraint on the name of the subscriber is applied. There is a first check in Javascript in the GUI, but there is also a check of the uniqueness of the names on the server side.&lt;br /&gt;&lt;br /&gt;Before going deeper, I just need to say a word about the structure used :&lt;br /&gt;&lt;br /&gt;To store the subscribers, I use a SuperColumnFamily, with the ID of the poll as key. For a poll having key "1234", it gives me something like :&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;"1234" =&gt; {&lt;br /&gt;   "subscriberKey1" =&gt; { name = "subscriberName1", options = ... }&lt;br /&gt;   "subscriberKey2" =&gt; { name = "subscriberName2", options = ... }&lt;br /&gt;   ...&lt;br /&gt;}&lt;/blockquote&gt;The trick about the &lt;span style="font-style: italic;"&gt;subscriberKey*&lt;/span&gt; is to generate a unique ID based on a timestamp in order to be sorted by Cassandra.&lt;br /&gt;The key will be something like : currentTimestamp - ClusterNodeId - ThreadId. Adding the ThreadId into the key give me the guarantee that using the System.currentTimeMillis() will be unique, because the processing will unfortunately take more than a millisecond :)&lt;br /&gt;&lt;br /&gt;Using this key, I will write the subscriber row with ConsistencyLevel.QUORUM, and then I will read all the rows till the one I have inserted (with ConsistencyLevel.QUORUM again).&lt;br /&gt;At this point I use Cassandra magic (rows are ordered) to be sure that I have selected all the subscribers they subscribe &lt;span style="font-weight: bold;"&gt;before&lt;/span&gt; the current one.&lt;br /&gt;I remains me to check manually the uniqueness of the name. If another row has the same name, I will simply remove the current subscriber.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Limiting the number of subscribers per option&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Another constraint I have implemented is the limitation of the number of subscribers per option.&lt;br /&gt;&lt;br /&gt;The principle is the same as the unique name constraint : I count the number of previously inserted subscriber.&lt;br /&gt;One point to keep in mind is that we can read a row with a duplicated name, which will be deleted later so it should not be taken into account for the actual constraint. This mean that we need to check if we are not counting duplicated names in this constraint too...&lt;br /&gt;&lt;br /&gt;But the good news about this constraint is that it show a way to implement counters in Cassandra. Maybe I will write another post about this topic. The bad news is that we need to check the duplicated names in several places.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Limitation of the model&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Complexity&lt;/span&gt; : adding more constraints grows the complexity in  O(n^2), as every new constraints (duplicated names) should be implemented into every other constraints (limitation of subscribers per option).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Scalability&lt;/span&gt; : this model will scale very well for billions of polls with some tens of users. The inverse, some tens of polls with billions of users, needs a lot of resources for checking constraint, which will make the performance drop.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2383658379882692325?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2383658379882692325/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2383658379882692325' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2383658379882692325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2383658379882692325'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2010/04/implementing-unique-constraints-with.html' title='Implementing unique constraints with Cassandra'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-7432546396050489918</id><published>2010-04-24T19:45:00.003+02:00</published><updated>2010-04-24T20:29:47.183+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><category scheme='http://www.blogger.com/atom/ns#' term='doodle clone'/><title type='text'>Doodle clone with Cassandra backend</title><content type='html'>I follow &lt;a href="http://cassandra.apache.org"&gt;Cassandra&lt;/a&gt;'s activity for some months now, and I decided to try it. But what better than developing a small application to test real needs ?&lt;br /&gt;&lt;br /&gt;That's what I did with my "&lt;a href="http://doodle.noisette.ch"&gt;Doodle clone with Cassandra backend&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;What is Cassandra ?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;According to the main page,&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;Cassandra is a highly scalable, eventually consistent, distributed, structured key-value store&lt;/blockquote&gt;&lt;span style="font-size:130%;"&gt;Why a Doodle clone ?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'm working during my free time on an &lt;a href="http://www.groople.ch"&gt;event manager&lt;/a&gt; software, so it was a good pretext to analyze Doodle business :)&lt;br /&gt;It appears to be quite simple, so it was a good starting point.&lt;br /&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class=" on down" style="display: block;" id="formatbar_CreateLink" title="Lien" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Which features to implement ?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I added the following feature to the doodle clone :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Easy (easier) to create polls&lt;/li&gt;&lt;li&gt;Login free, secret key based administration &lt;/li&gt;&lt;li&gt;No options limitation&lt;/li&gt;&lt;li&gt;Email feedback when someone subscribe the poll (if email provided)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;No duplicate name of the subscribers&lt;/li&gt;&lt;li&gt;An optional limitation of the number of subscribers per options&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;Have a look&lt;/span&gt; !&lt;br /&gt;&lt;br /&gt;Go to &lt;a href="http://doodle.noisette.ch"&gt;http://doodle.noisette.ch&lt;/a&gt; and try it, the result is really surprising.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Disclaimer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; There is absolutely no affiliation with Doodle, neither any idea to become the next Doodle. The goal of this application is purely academic, and it is deployed as is, without any guarantee.&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class=" on down" style="display: block;" id="formatbar_CreateLink" title="Lien" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-7432546396050489918?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/7432546396050489918/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=7432546396050489918' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7432546396050489918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7432546396050489918'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2010/04/doodle-clone-with-cassandra-backend.html' title='Doodle clone with Cassandra backend'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-8967207462857223988</id><published>2010-04-05T13:13:00.004+02:00</published><updated>2010-04-05T13:22:02.803+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nosql'/><title type='text'>Don't be abused by the term "commodity hardware"</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/NoSQL"&gt;NoSQL paradigm&lt;/a&gt; claims to build clusters of "commodity hardware". But don't be abused by this term : "commodity hardware" is not your living room's computer. Commodity hardware is two slots' computer, 16+GB RAM, (ten)giga ethernet, raid5 hard disks.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Commodity hardware is not 500$ computers. It's 5000$ computers. But building a 10 nodes' cluster for 50'000$ is still really cheap.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And remeber : clusters' primary bottlneck is I/O. Both disk and network. So there is no place for virtualisation here.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-8967207462857223988?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/8967207462857223988/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=8967207462857223988' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8967207462857223988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8967207462857223988'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2010/04/dont-be-abused-by-term-commodity.html' title='Don&apos;t be abused by the term &quot;commodity hardware&quot;'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-664568960075243033</id><published>2009-12-30T11:46:00.007+01:00</published><updated>2009-12-31T19:23:00.726+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><category scheme='http://www.blogger.com/atom/ns#' term='scalability'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrent'/><title type='text'>Sequences scalability</title><content type='html'>Sequences are central part of most computer systems. They are used both in technical part (generate unique identifier for object) and in business part (count the remaining free tickets which can be sold).&lt;br /&gt;&lt;br /&gt;When the load on the application goes higher, sequences become quickly central bottlenecks of systems. So the goal here is to first categorize different types of sequences and then gives some keys to see how sequences be distributed to increase their scalability, and hence the global scalability of the whole system.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Characteristics of sequences : &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Order&lt;/span&gt; : the number generate should be used in a given order (ascendant or descendant), or the order do not matter. I will talk about &lt;span style="font-style: italic;"&gt;ordered&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;unordered&lt;/span&gt; sequence.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Missing values&lt;/span&gt; : some values can be missing in the sequence. For example the sequence miss the value 4 should not alter the behavior of the application. I will talk about &lt;span style="font-style: italic;"&gt;continued&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;discontinued&lt;/span&gt; sequence.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Finite sequence&lt;/span&gt; : all the values of the sequence are know and countable. Countable sequences are particular case of finite sequence where the sequence has a reasonable amount of values, and thus could be represented by one object per values. I will talk about &lt;span style="font-style: italic;"&gt;finite&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;infinite&lt;/span&gt; sequence, and &lt;span style="font-style: italic;"&gt; countable&lt;/span&gt; sequence.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Key to distribute sequences&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Discontinued sequences are easy to scale : the application can pick numbers n by n in the sequence, reducing the amount of calls to the sequence by n. Good example for of discontinued sequences are   objects identifier generators.&lt;br /&gt;&lt;br /&gt;Unordered sequences are also easy to scale : a counter can be decomposed in n subcounter, picking at random one of the subcounter to increment or decrement will reduce the contention on one counter by n. A typical example is a quantity of object to sell. N subcounters are initialized with the sum is the total amount to sell. The object cannot be sold anymore when every subcounters are at 0.&lt;br /&gt;&lt;br /&gt;Countable sequences can be scaled by representing every value of the sequence as a single object in the database. Updating an unused object is a easy task.&lt;br /&gt;&lt;br /&gt;Finaly infinite, continued ordered sequence are very hard to scale because synchronization between all callers is required, so a single point of contention is mandatory.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sequences are choke point in most systems, but as we saw above they can scale relatively simply with two simple tricks : read number n by n instead of 1 by 1, or decompose a counter in n subcounters.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-664568960075243033?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/664568960075243033/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=664568960075243033' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/664568960075243033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/664568960075243033'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2009/12/sequences-scalability.html' title='Sequences scalability'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5866650845037124965</id><published>2009-11-15T20:44:00.006+01:00</published><updated>2009-11-15T21:46:16.628+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrent'/><title type='text'>Call different services, use the first to reply</title><content type='html'>&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;The needs&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My needs were the following : I have an arbitrary amount of &lt;i&gt;webservices&lt;/i&gt; to call, but I don't know, for a particular query, which one will return the answer. More than that, some are slower and others are faster, but again, I don't know which is the fastest for my particular query.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what I will do is to parallelize the queries, and use the value of the first which return my a good value.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Use an Executor&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first component to implement such a requirement is an &lt;i&gt;Executor&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;The &lt;i&gt;Executor&lt;/i&gt; will run all my queries, in as many threads as I want, permitting to fine tune the behavior of the system.&lt;/div&gt;&lt;div&gt;As many queries will input the system and will be translated in many more threads, it is important to use a limited amount of threads to not crash the system.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Synchronization on result&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A specific object will be used to synchronize the result : the first result will be returned to the caller, letting the running threads die, and no more threads will be run for this query.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some basic primitive for concurrent programming (&lt;i&gt;java.util.concurrent&lt;/i&gt;) will be used, such as &lt;i&gt;CountDownLatch&lt;/i&gt; : the caller will block on the latch, and once a thread will find the answer, it will set the value into the result and count down the latch. The caller will be freed and the value will be available.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Watchdog if all the queries fail&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One point to not forget is if every queries fail, the caller should be informed of this fail.&lt;/div&gt;&lt;div&gt;A watchdog will be used : it will block till all the threads executing the query will finish, and will then be run. Its only task is to free the caller. This one will continue the processing, but the result will not be available. This will be the responsibility of the caller to run user code to handle this special case.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Strong requirements&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The requirements are the following : &lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Use as little synchronization as possible&lt;/li&gt;&lt;li&gt;Use as much concurrent primitives (&lt;i&gt;java.util.concurrent&lt;/i&gt;) as possible&lt;/li&gt;&lt;li&gt;Do it as generic as possible&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Java implementation&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The interesting part of the implementation is given here below.&lt;/div&gt;&lt;div&gt;The Executor is simply an java.util.concurrent.Executor. I'm not good enough to implement a better solution than they do.&lt;/div&gt;&lt;div&gt;The result object is composed of the following attributes :&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;public class FutureResult&lt;t&gt; {&lt;/t&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;private T result;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;private boolean done;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;private AtomicInteger threadCount = new AtomicInteger(0);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;private CountDownLatch latch = new CountDownLatch(1);&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;A generic type for the value, a &lt;i&gt;AtomicInteger&lt;/i&gt; to count how many other threads are working on this result, and a latch to make the caller wait.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The watchdog class will simply wait till all the threads are finish and free the caller if it is not already the case :&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;span&gt;&lt;span&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;class WatchDogRunnable implements Runnable {&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;public void run() {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;while (result.hasThreadsWorking()) {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;synchronized (result) {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;result.wait(2000);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;latch.countDown();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;div&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;And finally an abstract callable worker which can be easily extended to run the wanted tasks. The call function will increment the &lt;i&gt;AtomicInteger&lt;/i&gt;, do the work if it is not already done, if a result is found, free the caller, decrement the &lt;i&gt;AtomicInteger&lt;/i&gt; and return the value if it is set. Not that the worker implementation will implement the callInternal function.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;public abstract class AbstractCallableWorker&lt;t&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;implements Callable&lt;t&gt; {&lt;/t&gt;&lt;/t&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;private FutureResult&lt;t&gt; result;&lt;/t&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;public final T call() {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;result.setOneMoreThread();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;if (!result.isDone()) {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;T callResult = callInternal();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;if (callResult != null) {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;setResult(callResult);&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;    &lt;/span&gt;latch.countDown();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;result.setOneLessWorkingThead();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;return result.getResult();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;protected abstract T callInternal();&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Everything put together, you can implement as much worker as you want and call as many &lt;i&gt;webservice&lt;/i&gt; as you want, with the only guaranty to get the caller continue with the fastest service to reply !&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5866650845037124965?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5866650845037124965/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5866650845037124965' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5866650845037124965'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5866650845037124965'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2009/11/call-different-services-use-first-to.html' title='Call different services, use the first to reply'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-1954780904409640287</id><published>2009-11-14T21:36:00.004+01:00</published><updated>2009-11-14T22:12:02.625+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cluster'/><category scheme='http://www.blogger.com/atom/ns#' term='j2ee'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='opensource'/><title type='text'>Clustering Jackrabbit 1.5.x with DataStore configuration</title><content type='html'>&lt;a href="http://jackrabbit.apache.org/"&gt;&lt;blockquote&gt;&lt;/blockquote&gt;Jackrabbit&lt;/a&gt; is the reference implementation of JSR-170 : JCR, Java Content Repository.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One day we felt the needs to run a Jackrabbit repository in a clustered environment for reliability. So a JCR runs on two separated servers, backed by the an Oracle db and a NFS shared datastore.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_9jdtZI7diwk/Sv8X-LaEkWI/AAAAAAAAALg/OANf1yG-ug4/s1600-h/jcr-cluster.png"&gt;&lt;img src="http://2.bp.blogspot.com/_9jdtZI7diwk/Sv8X-LaEkWI/AAAAAAAAALg/OANf1yG-ug4/s400/jcr-cluster.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5404064434849354082" style="cursor: pointer; width: 400px; height: 176px; " /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It exists some difficulties to run such architecture, mainly because both JCR nodes (JCR1 and JCR2) do not know each others. So if we insert some content on one node, it takes some time before we can read it on the other node.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In Jackrabbit&lt;span&gt;&lt;span&gt; 1.5.x, &lt;i&gt;Session.refresh&lt;/i&gt; do not work correctly, s&lt;/span&gt;&lt;/span&gt;o we need to do some trick to enable cluster (synchronization) features.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First of all, we add a custom &lt;i&gt;ServletFilter&lt;/i&gt; which handle the GET (read) request and transform it on a HEAD one (test if the content exists) using &lt;i&gt;apache.commons.HttpClient&lt;/i&gt;.&lt;/div&gt;&lt;div&gt;If the return of the query says the content exists, then we run the normal request. If the content do not exists, we way for some arbitrary time and relaunch the HEAD request.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This filter will let enough time to the node to synchronize itself, and then perform the query in the right way.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Other possibilities like HEAD on the current node and then HEAD on a different node should also be possible, but this will require every nodes to know about every other nodes. No the best idea.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One another tricky point is to store all the content to the configured datastore. Be carefull to not rely on a JNDI persistence manager, but be sure to use a subclass of a bundle persistence manager, otherwise you will have some surprise with the size of the database.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-1954780904409640287?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/1954780904409640287/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=1954780904409640287' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1954780904409640287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1954780904409640287'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2009/11/clustering-jackrabbit-15x-with.html' title='Clustering Jackrabbit 1.5.x with DataStore configuration'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_9jdtZI7diwk/Sv8X-LaEkWI/AAAAAAAAALg/OANf1yG-ug4/s72-c/jcr-cluster.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-6209340364235914532</id><published>2009-01-17T18:24:00.007+01:00</published><updated>2011-01-06T12:39:08.538+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='j2ee'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Des nombres à usage unique (nonce)</title><content type='html'>Afin de répondre à une problématique de transmission d'informations sensibles sur un réseau pas sûr (Internet donc...), une solution est l'utilisation de nonce, diminutif de &lt;span style="font-style: italic;"&gt;number used once&lt;/span&gt;, nombre à usage unique.&lt;br /&gt;&lt;br /&gt;Ils sont utilisé pour mettre du sel dans des informations sensibles qui seront ensuite hashées et transmises en clair sur le réseau. Mais leur efficacité n'est effective seulement si on a la garantie qu'un même nonce ne va jamais être utilisé 2 fois !&lt;br /&gt;&lt;br /&gt;Exemple type : vous développez un service d'authentification, mais celui-ce ne peut se faire sur du SSL. Vous souhaitez toutefois que si une personne intercepte les informations, elle ne puisse pas les réutiliser pour s'identifier à son tour.&lt;br /&gt;&lt;br /&gt;Le seul hashage du mot de passe ne suffisant pas car la personne qui a interceptée le mot de passe hashé pourra rejouer la séquence pour simuler sa connexion, une solution est de hasher le mot de passe concaténé au nonce (du style sha256("#" + mot de passe + "#" + nonce + "#")), puis de transmettre le nom d'utilisateur, le nonce utilisé et le résultat du hashage. Le serveur disposera ainsi de toutes les informations pour vérifier si le mot de passe utilisé pour le hashage était effectivement correcte ou pas. Les prochaines requêtes faites avec ce nonce seront systématiquement refusées.&lt;br /&gt;&lt;br /&gt;C'est pour faciliter l'accès à ces nombres que je mets à disposition un petit service de génération de nombre à unique, accessible publiquement à l'adresse&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;http://nonce.noisette.ch/next&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Chaque appel à cette url retourne un chaine de 32 caractères composées des lettres a-z, A-Z et les chiffres 0-9. Notez que les chaines retournées sont donc senible à la casse.&lt;br /&gt;&lt;br /&gt;Le nombre de nonce possible est donc (26+26+10)^32 = 2.27 * 10^57, soit à peu près &lt;a href="http://fr.wikipedia.org/wiki/Nombre_parasite"&gt;6-parasite&lt;/a&gt;, ou beaucoup plus que d'atomes dans l'univers.&lt;br /&gt;&lt;br /&gt;A utiliser sans modération pour toute application nécessitant la transmission d'informations sensibles sur un réseau non sécurisé.&lt;br /&gt;&lt;br /&gt;Edit (06.01.2011) : GAE ne supporte plus le proxying, vous pouvez essayer l'app directement sur &lt;a href="http://noisette-nonce.appspot.com/"&gt;http://noisette-nonce.appspot.com/&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-6209340364235914532?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/6209340364235914532/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=6209340364235914532' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6209340364235914532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6209340364235914532'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2009/01/des-nombres-usage-unique-nonce.html' title='Des nombres à usage unique (nonce)'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2925541384205042937</id><published>2008-06-08T20:00:00.000+02:00</published><updated>2008-06-08T20:23:18.737+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='proxy'/><title type='text'>Implémentation d'un serveur proxy HTTP</title><content type='html'>La question à la base de cet article est la suivante :&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;Comment faire pour que mes concurrents ne soient pas au courant que j'observe (très) régulièrement une section particulière de leur site internet ?&lt;/blockquote&gt;La première étape bien évidemment est de la légitimer cette question. Comment un concurrent pourrait savoir que je consulte régulièrement son site ?&lt;br /&gt;&lt;br /&gt;La réponse est simple. Prenons un cas concret pour illustrer : &lt;a href="http://www.elca.ch/"&gt;ELCA Informatique&lt;/a&gt; possède les plages d'adresses ips 193.72.144.0 - 193.72.147.255 (bloc /22 = 1024 ips, hosté chez Cablecom) et 193.73.238.0 - 193.73.238.255 (bloc /24 = 256 ips, hosté chez Sunrise)&lt;br /&gt;&lt;br /&gt;Ce genre d'info se trouve très facilement via un mélange &lt;span style="font-style: italic;"&gt;whois&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;traceroute&lt;/span&gt; et autres informations DNS.&lt;br /&gt;&lt;br /&gt;Une fois qu'on a ces ips, il suffit de rechercher dans les logs les hits faits par ces ips et on pourra dresser un profil précis des intérêts des collaborateurs d'ELCA sur notre site.&lt;br /&gt;&lt;br /&gt;Donc comment faire pour éviter cette traçabilité ?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Connexion Internet à adresse ip dynamique (xDSL)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Une première solution est d'utiliser une connexion xDSL pour toutes les connexions humaines à Internet, et de dédier exclusivement les plages d'ips fixes et repérables aux services de l'entreprise. Cette pratique est de plus en plus courante, surtout avec l'arrivée des connexions VDSL et de boitiers qui permettent d'agréger plusieurs lignes xDSL afin d'une part d'avoir un redondance, et d'autre part de partager la somme des débits des lignes entre les utilisateurs. Le seul détail concernant cette solution est de vérifier que l'adresse ip change réellement, faute de quoi il faudrait forcer ce changement.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Serveur proxy&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Une autre solution, que je vais détailler ici car elle est plus intéressante d'un point de vue ingénierie informatique, est de faire passer le traffic des utilisateurs par un proxy. Par proxy j'entends tout type de connexion indirect à Internet, donc autant les serveurs proxy HTTP, SOCKS, etc que les réseaux de proxy comme par exemple &lt;a href="http://fr.wikipedia.org/wiki/Tor_%28r%C3%A9seau%29"&gt;Tor&lt;/a&gt;.&lt;br /&gt;Le fait d'accéder à Internet par l'intermédiaire d'un proxy permet de visualiser un site avec une adresse ip qui n'est pas notre, mais appartient à un prestataire de ce genre de service. Cependant l'anonymité à 100% n'existe pas : il existera toujours un intermédiaire qui saura qui a accédé où. La confiance des intermédiaires est donc de mises dans cette configuration.&lt;br /&gt;&lt;br /&gt;Il existe une grande quantité de serveur proxy logiciel de qualité, open source ou commercial, comme par exemple &lt;a href="http://www.squid-cache.org/"&gt;Squid&lt;/a&gt;, &lt;a href="http://www.privoxy.org/"&gt;Privoxy&lt;/a&gt;, &lt;a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html"&gt;Apache mod_proxy&lt;/a&gt;, etc... Mais une fois de plus, l'utilisation d'un logiciel existant nous priverait du plaisir de développer de notre propre implémentation.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Principe de base&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Le principe d'un serveur proxy est donc d'intercepter la requête d'un navigateur, d'ouvrir une connexion vers le site cible, transmettre la requête original, lire le résultat et finalement renvoyer ce résultat au navigateur.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Protocole HTTP&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;La partie centrale d'un serveur proxy HTTP réside sa compréhension du protocole HTTP. Celui-ci comporte des particularités qui vont être détaillées.&lt;br /&gt;&lt;br /&gt;Le serveur proxy va recevoir une requête du navigateur, dont la première ligne comporte l'action à exécuter, l'url de la cible et une éventuelle version du protocole utilisé :&lt;br /&gt;&lt;blockquote&gt;GET http://www.noisette.ch/ HTTP/1.0&lt;/blockquote&gt;Cette première ligne va donc directement nous renseigner sur le serveur cible à connecter. Le reste de la requête est composée de lignes de header, contenant diverses informations sur la requête comme le navigateur utilisé ou le &lt;span style="font-style: italic;"&gt;referer&lt;/span&gt; (en français on dit comment ?).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Transfer de la requête au serveur cible&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;La prochaine étape est le transfert de la requête au serveur cible. A ce moment on peut éventuellement modifier ou enlever des headers du client, voir en ajouter d'autres. Plus précisément, il peut être intéressant de filtrer tous les headers des clients qui pourraient trahir l'utilisateur du proxy (&lt;span style="font-style: italic;"&gt;information leakage&lt;/span&gt;).&lt;br /&gt;Reste la lecture du résultat, qui n'est de loin pas la partie la plus triviale.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ne pas bufferiser la lecture du résultat&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;L'implémentation d'un serveur proxy dans laquelle on lit le résultat en entier (via un lib du style httpclient) avant de l'envoier ensuite au navigateur n'est à mon avis pas bonne : le délai entre la requête et la réponse risque d'en prendre un coup, surtout pour les grosses pages.&lt;br /&gt;L'idée est donc de retourner directement les bytes lus du serveur web au client.&lt;br /&gt;&lt;br /&gt;En pseudo code, ca donne quelque chose du style :&lt;br /&gt;&lt;pre&gt; // fromWeb : InputStream du socket de la connexion vers le serveur source&lt;br /&gt;// toBrowser : OutputStream du socket de la connexion vers le browser&lt;br /&gt;while ((i = fromWeb.read(buffer)) != -1) {&lt;br /&gt;  toBrowser.write(buffer, 0, i);&lt;br /&gt;  toBrowser.flush();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Fermeture des connexions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;La fermeture des connexions est très importante afin de libérer les ressources et ne pas avoir un serveur qui explose après 20 requêtes. Facile en théorie, la fermeture de la connexion est la sous partie non triviale. Dans la mesure où le serveur ne ferme pas systématiquement la connexion à la fin du transfert si il reçoit un header "&lt;span style="font-style: italic;"&gt;Connection: keep-alive&lt;/span&gt;", il faut détecter quand la réponse du serveur est complète pour pouvoir fermer la connexion.&lt;br /&gt;&lt;br /&gt;Dans une grande majorité des réponses, la taille de la réponse est spécifiée via un header "Content-Length: 82". Il suffit donc de lire autant de bytes que nécessaire et la connexion peut être fermée. Mais quelques réponses ne vont pas retourner de taille. C'est le cas par exemple lors du streaming d'un fichier. Dans ce cas il faut lire la réponse jusqu'à ce que le serveur ferme lui-même la connexion.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Transfer-Encoding: chunked&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Une autre difficulté à la lecture de la réponse est l'encodage &lt;span style="font-style: italic;"&gt;chunked&lt;/span&gt;. Dans ce mode de transfert, le serveur sépare la réponse en plusieurs parties, les &lt;span style="font-style: italic;"&gt;chunks&lt;/span&gt;. Ca lui permet d'envoyer une partie de la réponse tout en calculant la suite. Par exemple Google utilise ce mode de réponse : les 2-3 premiers résultats sont dans un cache direct, et Google les retourne dans un premier chunk. Puis il doit aller chercher les 7-8 autres dans un deuxième cache, opération un peu plus coûteuse, qui se fait pendant que le navigateur du client lit ce premier &lt;span style="font-style: italic;"&gt;chunk&lt;/span&gt;. Ca permet au serveur de ne pas attendre d'avoir entièrement cherché les 10 résultats, et de profiter du temps de transfert avec le client. Du point de vu du client, une fois qu'il a fini de lire le premier chunk, les suivants sont prêts à être lus. L'impression de fluidité est donc parfaite. Mais malheureusement peu d'implémentations tirent intelligemment profit de ce type de transfert.&lt;br /&gt;&lt;br /&gt;En pratique, la réponse d'une encodage &lt;span style="font-style: italic;"&gt;chunked&lt;/span&gt; donne quelque chose du style :&lt;br /&gt;&lt;blockquote&gt;taille du chunk en hexa \r\n&lt;br /&gt;données \r\n&lt;br /&gt;taille du prochain chunk \r\n&lt;br /&gt;données \r\n&lt;br /&gt;...&lt;br /&gt;0\r\n&lt;br /&gt;\r\n&lt;/blockquote&gt;Pour lire la réponse, il faut donc lire la taille du &lt;span style="font-style: italic;"&gt;chunk&lt;/span&gt;, lire les données du &lt;span style="font-style: italic;"&gt;chunk&lt;/span&gt;, lire la taille du prochain &lt;span style="font-style: italic;"&gt;chunk&lt;/span&gt;, etc jusqu'à ce qu'on ait un &lt;span style="font-style: italic;"&gt;chunk&lt;/span&gt; de taille null, signifiant la fin de la réponse.&lt;br /&gt;&lt;pre&gt;HTTP/1.1 200 OK¶&lt;br /&gt;Date: Fri, 31 Dec 1999 23:59:59 GMT¶&lt;br /&gt;Content-Type: text/plain¶&lt;br /&gt;Transfer-Encoding: chunked¶&lt;br /&gt;¶&lt;br /&gt;1a¶&lt;br /&gt;abcdefghijklmnopqrstuvwxyz¶&lt;br /&gt;10¶&lt;br /&gt;1234567890abcdef¶&lt;br /&gt;0¶&lt;br /&gt;¶&lt;/pre&gt;&lt;span style="font-size:130%;"&gt;Caching&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Prochaine étape dans l'implémentation d'un serveur de cache utile est efficace, c'est l'ajout d'une couche de cache au niveau du proxy : le serveur cible va retourner une information sur la date de dernière modification de la page. Cette indication peut être utilisé pour retourner la page mise en cache plutôt que de relire la réponse du serveur.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Authentification &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Dernier point important si on met un serveur proxy sur internet, il faut ABSOLUMENT implémenter un ACL (access control list) afin de restreindre l'accès et l'utilisation du proxy aux personnes authentifiées uniquement. Faute de quoi votre tout beau serveur proxy sera vitre trouvé et utilisé par des personnes malveillantes pour spammer, consulter des sites illégaux etc.&lt;br /&gt;&lt;br /&gt;Prochaine étape : au travail !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2925541384205042937?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2925541384205042937/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2925541384205042937' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2925541384205042937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2925541384205042937'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2008/06/implmentation-dun-serveur-proxy-http.html' title='Implémentation d&apos;un serveur proxy HTTP'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-457285031185346163</id><published>2008-06-05T06:21:00.004+02:00</published><updated>2008-06-08T20:17:25.490+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smtp'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Mettre à mal un réseau d'entreprise avec Outlook (TM, R &amp; CO)</title><content type='html'>Suite à une expérience involontaire d'un collègue de travail, on a eu 30 ordinateurs bloqués une quinzaine de minute :&lt;br /&gt;&lt;br /&gt;Notre serveur SVN envoie un mail à chaque commit à une mailinglist interne, à laquelle une trentaine de collaborateurs est abonné. Le commit incriminé était certes quelque peu conséquent, une colonne ajoutée dans un fichier CSV de 5000 lignes, mais la conséquence était désastreuse !&lt;br /&gt;&lt;br /&gt;Le mail faisait ~ 5Mb, et le diff du commit était formaté en HTML. Tous les collaborateurs qui ont cliqué sur le mail avec le preview activé n'ont pas eu d'autre choix que de tuer Outlook après avoir eu l'ordinateur bloqué un bon moment.&lt;br /&gt;&lt;br /&gt;Moi qui n'était déjà pas un grand amoureux d'Outlook et de son immense capacité à accomplir des recherches performante parmi les mails, me voici comblé.&lt;br /&gt;&lt;br /&gt;Mais pourquoi donc autant d'entreprise s'accrochent-ils à ce logiciel ? Dans tous les cas, si vous voulez forcer un peu la main pour le passage à un autre logiciel, vous savez ce qu'il reste à faire.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-457285031185346163?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/457285031185346163/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=457285031185346163' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/457285031185346163'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/457285031185346163'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2008/06/mettre-mal-un-rseau-dentreprise-avec.html' title='Mettre à mal un réseau d&apos;entreprise avec Outlook (TM, R &amp; CO)'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-8357443813819199630</id><published>2008-02-23T13:42:00.000+01:00</published><updated>2008-02-23T12:42:55.200+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='seo'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='browser'/><title type='text'>Une liste de USER AGENTS parsable</title><content type='html'>Il est toujours utile d'avoir sous la main une liste de USER AGENTS facilement &lt;span style="font-style: italic;"&gt;parsable&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;La mienne, qui ne contient que des USER AGENTS ^Mozilla/.* se trouve à l'adresse &lt;a href="http://www.noisette.ch/useragents/"&gt;http://www.noisette.ch/useragents/&lt;/a&gt;. Elle est mises-à-jour journalièrement sur la base des navigateurs qui se connectent sur mon serveur, tous sites confondus. Elle va donc suivre l'évolution des numéros de version des Firefox et autres IE...&lt;br /&gt;&lt;br /&gt;Cette liste, couplée à la fonction &lt;a href="http://benoitperroud.blogspot.com/2007/11/fonction-urlgetcontents-en-php.html"&gt;url_get_contents &lt;/a&gt; définie antérieurement, permet facilement de disposer d'un USER AGENT pour faire ce qu'il est possible de faire avec un USER AGENT généré :)&lt;br /&gt;&lt;br /&gt;Illustration en PHP :&lt;br /&gt;&lt;pre&gt;$useragents = explode("\n", url_get_contents('http://www.noisette.ch/useragents/list.txt'));&lt;br /&gt;$useragent = $useragents[rand(0, count($useragents) - 1)];&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-8357443813819199630?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/8357443813819199630/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=8357443813819199630' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8357443813819199630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8357443813819199630'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2008/02/list-de-user-agents-exploitable.html' title='Une liste de USER AGENTS parsable'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-1524269656106851496</id><published>2008-02-18T12:53:00.000+01:00</published><updated>2008-02-18T11:55:19.545+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='optimisation'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><title type='text'>De la concurrence des requêtes SQL</title><content type='html'>Sans cité &lt;a href="http://fr.wikipedia.org/wiki/Michel_de_Montaigne"&gt;Montaigne&lt;/a&gt;, voici un cas académique dans lequel la concurrence des requêtes SQL est souvent oubliée.&lt;br /&gt;&lt;br /&gt;Nous avons une table &lt;span style="font-style: italic;"&gt;hits&lt;/span&gt; qui contient 4 champs : une date (nommé &lt;span style="font-style: italic;"&gt;date&lt;/span&gt;), une clé étrangère pointant vers un objet du système (nommée &lt;span style="font-style: italic;"&gt;object_id&lt;/span&gt;) et un compteur implémenté sous ca forme la plus simple : un entier (nommé &lt;span style="font-style: italic;"&gt;counter&lt;/span&gt;). Puisqu'on travail avec une framework qui implémente de l'&lt;a href="http://en.wikipedia.org/wiki/Active_record_pattern"&gt;&lt;span style="font-style: italic;"&gt;active record&lt;/span&gt;&lt;/a&gt; on ajoute un champ &lt;span style="font-style: italic;"&gt;id&lt;/span&gt; qui fera office de clé primaire.&lt;br /&gt;A chaque utilisation de l'objet référencé par la clé étrangère on souhaite incrémenter le compteur et recommencer à 0 tous les minuits afin d'avoir un historique journalier de l'utilisation de l'objet. Alors comme on a quand même un peu réfléchi à la performance du système (un billet sur le sujet est en préparation), on définit un index composé des champs &lt;span style="font-style: italic;"&gt;date&lt;/span&gt; et &lt;span style="font-style: italic;"&gt;object_id&lt;/span&gt;. Puis on définit la fonction suivante, donnée ci-dessous en pseudo-code, qui incrémente notre compteur et insère un nouveau tuple si aucun n'existe pour le jour courant :&lt;br /&gt;&lt;pre&gt;void function hit ( int $object_id ) {&lt;br /&gt;  SELECT FROM hits WHERE object_id = $object_id AND date = NOW()&lt;br /&gt;  if (row_exists)&lt;br /&gt;      UPDATE hits SET counter = counter + 1 WHERE  object_id = $object_id AND date = NOW()&lt;br /&gt;  else&lt;br /&gt;      INSERT INTO hits (object_id, date, counter) VALUES ($object_id, NOW(), 1)&lt;br /&gt;}&lt;/pre&gt;Tout se passe bien jusqu'au jour où on se rend compte qu'il y a plusieurs lignes par objet et par jour dans la base de données.&lt;br /&gt;&lt;br /&gt;Ce problème vient du fait qu'il peut se passer un temps indéterminé entre la requête &lt;span style="font-style: italic;"&gt;SELECT&lt;/span&gt; et l'&lt;span style="font-style: italic;"&gt;INSERT&lt;/span&gt;. Si à 00h01 2 requêtes sont faites en même temps sur le même objet, il est fort probable que 2 requêtes &lt;span style="font-style: italic;"&gt;SELECT&lt;/span&gt; soient faites avant un &lt;span style="font-style: italic;"&gt;INSERT&lt;/span&gt;, et donc les 2 tests&lt;span style="font-family:monospace;"&gt; &lt;/span&gt;&lt;span style="font-style: italic;"&gt;if (row_exists)&lt;/span&gt; vont retourner faux et 2 &lt;span style="font-style: italic;"&gt;INSERT&lt;/span&gt; seront fait.&lt;br /&gt;&lt;br /&gt;Les solutions pour résoudre ce problème sont multiples, elles passent de la redéfinition de la clé primaire en &lt;span style="font-style: italic;"&gt;date&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;object_id&lt;/span&gt; plutôt que notre champ &lt;span style="font-style: italic;"&gt;id&lt;/span&gt;, ce qui aurait comme comportement de faire échouer le 2ème &lt;span style="font-style: italic;"&gt;INSERT&lt;/span&gt;, erreur qui pourrait être capturée et traitée spécifiquement. Une autre solution serait de mettre un verrou sur la fonction, chose très aisée en Java avec le mot-clé &lt;span style="font-style: italic;"&gt;synchronized&lt;/span&gt;. La fonction deviendrait &lt;span style="font-style: italic;"&gt;void synchronized function hit(int object_id)&lt;/span&gt;, évitant ainsi ce type de problème de concurrence.&lt;br /&gt;&lt;br /&gt;Dans tous les cas les applications web sont aussi (voir même plus) soumises aux problèmes de concurrence, et l'expérience nous montre que la technique de l'autruche de même que les phrases du style "Il ne PEUT PAS y avoir 2 requêtes en même temps" sont à bannir absolument.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-1524269656106851496?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/1524269656106851496/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=1524269656106851496' title='4 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1524269656106851496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1524269656106851496'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2008/02/de-la-concurrence-des-requtes-sql.html' title='De la concurrence des requêtes SQL'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-6263699928333617862</id><published>2008-01-29T11:16:00.000+01:00</published><updated>2008-01-29T11:34:45.044+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='privacy'/><title type='text'>Vos données sont-elles réellement privées ?</title><content type='html'>&lt;span style="font-size:130%;"&gt;Donnez des informations pour exister&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Le principe premier du Web 2.0 est la participation des utilisateurs. Pour les sites sociaux comme MySpace et Facebook, où la participation se calcule en quantité d'informations données sur soi-même.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Collecte indirecte d'informations&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;L'aspect de collaboration entre les membres résulte en une masse d'information indirecte enregistrée souvent au dépend de la personne ciblée :&lt;br /&gt;&lt;br /&gt;Facebook par exemple enregistre des informations sur vous par rapport aux détails que donnent vos amis (appelé Social map) : à chaque ajout de nouvel &lt;span style="font-style: italic;"&gt;ami&lt;/span&gt;, vous avez la possibilité de spécifier comment vous l'avez connu. Grâce à ce système subtile, mon profile Facebook sait maintenant que j'ai fini l'EPFL en 2007, que je fais partie d'autres associations, ... alors que je n'ai rien renseigner sur ces sujets précis.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;Le business des données personnelles&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Le fait d'être encouragé à compléter son profil qui n'est complet qu'a 88% comme nous l'indique de manière bien visible Linkedin n'est pas entièrement désintéressé : le fait de connaitre précisément ses utilisateurs et d'en dresser des profils augmentent largement les marges sur les revenus publicitaires qui seront mieux ciblés donc plus percutant donc plus &lt;span style="font-style: italic;"&gt;intéressant&lt;/span&gt; pour l'utilisateur. Revenus publicitaires qui sont, rappelons-le, le &lt;span style="font-style: italic;"&gt;business model&lt;/span&gt; principal des ces sites sociaux.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Protection des données&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;L'aspect à ne pas perdre de vu si on utilise ce genre de sites, c'est que ça n'est pas une simple cas à cocher "Rendre mon profil privé" qui protègera réellement les données de votre profile : les données sont chez une personne tierce qui d'un jour à l'autre peut décider d'en faire autre chose. Ou, comme c'est le cas sur MySpace, une vulnérabilité du site permet d'outerpasser cette coche ridicule...&lt;br /&gt;&lt;br /&gt;La réponse au titre du billet est clairement NON ! Le fait de déposer vos données sur un service externe quelconque ne les rendent pas privées. Donc soit vous ne mettez que des informations &lt;span style="font-weight: bold;"&gt;réellement publiques&lt;/span&gt; sur votre profil, soit vous faites confiance à 100% au service et vous ne vous demanderez pas d'où viennent les données sur vous retrouvées dans la nature...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Ils en parlent&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Faille de sécurité qui perment de voir les photos privée d'un profil sur Myspace : &lt;a href="http://www.wired.com/politics/security/news/2008/01/myspace_torrent"&gt;http://www.wired.com/politics/security/news/2008/01/myspace_torrent&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Nos données personnelles sur Facebook : &lt;a href="http://standblog.org/blog/post/2008/01/10/De-lavenir-de-Facebook-et-de-nos-donnees-personnelles"&gt;http://standblog.org/blog/post/2008/01/10/De-lavenir-de-Facebook-et-de-nos-donnees-personnelles&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Système de publicité intrusive sur Facebook : &lt;a href="http://www.infos-du-net.com/actualite/12304-facebook-publicite-internautes.html"&gt;http://www.infos-du-net.com/actualite/12304-facebook-publicite-internautes.html&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-6263699928333617862?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/6263699928333617862/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=6263699928333617862' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6263699928333617862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6263699928333617862'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2008/01/vos-donnes-sont-elles-rellement-prives.html' title='Vos données sont-elles réellement privées ?'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2231561896167883878</id><published>2007-12-30T22:39:00.000+01:00</published><updated>2007-12-30T23:46:20.784+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>Je télécharge mes MP3 et les écoute légalement.</title><content type='html'>Le parlement et le conseil national ont accepté le 5 Octobre 2007 presque sans aucune résistance une &lt;a href="http://www.ige.ch/F/jurinfo/j103.shtm"&gt;loi fédérale sur le droit d'auteur et les droits voisins&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Pour toute question à propos du référendum lancé, que dit en passant j'encourage fortement à signer, rendez-vous sur le site &lt;a href="http://www.no-dmca.ch/"&gt;No Swiss DMCA&lt;/a&gt;.&lt;br /&gt;Je n'essayerai pas non plus de déterminer à quelles mesures techniques, notées &lt;span style="font-style: italic;"&gt;efficaces&lt;/span&gt;, le texte de loi fait peut bien faire référence.&lt;br /&gt;&lt;br /&gt;Cette loi, plus précisément l'article 39a alinéa 4 donné ci-après, combiné à l'approbation du Tribunal fédéral (TF) sur l'introduction d'une redevance sur les supports numériques (baladeurs MP3, iPod et autres enregistreurs à disques durs) entrée en vigueur au 1er septembre 2007, me mène à la conclusion suivante :&lt;br /&gt;&lt;br /&gt;Je vais télécharger de la musique sur mon réseau peer-to-peer préféré, &lt;a href="http://fr.wikipedia.org/wiki/Ripper"&gt;ripper&lt;/a&gt; des CDs et retirer les DMA de mes MP3 restants (autrement dit : contourner les mesures techniques &lt;span style="font-style: italic;"&gt;efficaces&lt;/span&gt;) et l'écouter (exclusivement) sur mon baladeur MP3 récemment acquis. Celui-ci étant taxé, je m'affranchis de toute autre taxe, et je deviens entièrement légal. Idem pour les divx !&lt;br /&gt;&lt;blockquote&gt;Art 39a&lt;br /&gt;4 L’interdiction de contourner ne peut pas frapper celui qui contourne une mesure technique efficace exclusivement dans le but de procéder à une utilisation licite.&lt;/blockquote&gt;PS : cet article n'est pas illégale au sens de l'Art 39a 3a, c'est-à-dire que cet article ne fait pas promotion visant à contourner des mesures techniques efficaces.&lt;br /&gt;PPS : la critique de la double imposition à une taxe sur les droits d'auteurs des musiques achetées sur un online music shop et écoutées sur un baladeur taxé fera l'objet d'un autre article.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2231561896167883878?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2231561896167883878/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2231561896167883878' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2231561896167883878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2231561896167883878'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/12/je-tlcharge-mes-mp3-et-les-coute.html' title='Je télécharge mes MP3 et les écoute légalement.'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2726925922373297212</id><published>2007-12-30T22:31:00.000+01:00</published><updated>2007-12-30T22:37:43.442+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='seo'/><category scheme='http://www.blogger.com/atom/ns#' term='wireless'/><title type='text'>Offrir un réseau wifi ouvert pour rentabiliser sa connexion Internet</title><content type='html'>J'écrivais il y a un bon moment comment un administrateur réseau peu scrupuleux pouvait &lt;a href="http://benoitperroud.blogspot.com/2006/09/gagner-de-largent-grce-aux-botnets.html"&gt;arrondir ses fins de mois en détournant les publicités des sites&lt;/a&gt; visités par les utilisateurs&lt;br /&gt;interne.&lt;br /&gt;&lt;br /&gt;Cette technique s'adapte très simplement à un réseau wifi ouvert...&lt;br /&gt;&lt;br /&gt;Mais attention au &lt;a href="http://en.wikipedia.org/wiki/Click-through_rate"&gt;click through rate&lt;/a&gt; trop élevé :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2726925922373297212?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2726925922373297212/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2726925922373297212' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2726925922373297212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2726925922373297212'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/12/offrir-un-rseau-wifi-ouvert-pour.html' title='Offrir un réseau wifi ouvert pour rentabiliser sa connexion Internet'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-3347246719893979057</id><published>2007-12-15T16:14:00.000+01:00</published><updated>2007-12-15T15:14:52.927+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='bullshit'/><title type='text'>Twitter, un vrai service Web 2.0 (le retour)</title><content type='html'>Pour commencer j'ose espérer que le 2ème degré du &lt;a href="http://benoitperroud.blogspot.com/2007/12/twitter-un-vrai-service-web-20.html"&gt;message précédent&lt;/a&gt; a été perçu.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt; est selon moi un vrai service Web 2.0, c'est-à-dire qu'il ne sert à rien. On n'est pas plus heureux en l'ayant découvert et ça ne fait pas avancer la société de l'utiliser.&lt;br /&gt;&lt;br /&gt;Mais au-delà de considération subjectives à son sujet, les technologies et les techniques d'addiction mises en oeuvre sur ce site sont suffisamment intéressantes pour être discutées ici :&lt;br /&gt;&lt;br /&gt;Premièrement les méthodes de publication disponibles sont autant multiples que variées :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Interface web,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;SMS,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;IM (client jabber),&lt;/li&gt;&lt;li&gt;...&lt;/li&gt;&lt;/ul&gt;On voit d'entrée que le service est fait pour être mis-à-jour en permanence, très facilement par IM quand on est devant un ordinateur relié à Internet, mais aussi via des dispositifs mobiles une fois le clavier de l'ordinateur hors de porté. Ainsi un utilisateur peut à tout moment renseigner ses lecteurs virtuels et potentiels sur ce qu'il est en train de faire. L'aspect mise-à-jour via téléphone portable est très important, car il permet de modifier le statut lors des sorties, donc quand c'est le plus croustillant.&lt;br /&gt;&lt;br /&gt;Un aspect important pour renforcer l'addiction est la possibilité d'émettre un rappel (SMS ou email) en cas de non mise-à-jour prolongée.&lt;br /&gt;&lt;br /&gt;Deuxièmement les différents formats de lecture possibles sont aussi standard que tendance : on retrouve ainsi la "&lt;span style="font-style: italic;"&gt;social timeline&lt;/span&gt;" sur sa page personnelle au style très épuré Web 2.0 et le fameux flux RSS. La communauté de lecteurs n'est pas en reste non plus, avec son lot de features pour se créer un réseau d'&lt;span style="font-style: italic;"&gt;amis&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Pour conclure sur cet article plutôt bullshit'stisant pour reprendre les termes d'autres, je dirais que mis à part le côté "sert-à-rien" il pourrait remplacer à merveille les blogs que les jeunes s'efforcent d'utiliser de la manière dont Twitter oblige, la possibilité de mettre les photos en mois. Et que le côté publication d'activité via IM est réellement bien fait.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-3347246719893979057?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/3347246719893979057/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=3347246719893979057' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3347246719893979057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3347246719893979057'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/12/twitter-un-vrai-service-web-20-le.html' title='Twitter, un vrai service Web 2.0 (le retour)'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5892447238518830616</id><published>2007-12-15T13:24:00.000+01:00</published><updated>2007-12-15T12:24:53.143+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web 2.0'/><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Twitter, un vrai service Web 2.0</title><content type='html'>D'abord il y a eu les &lt;a href="http://fr.wikipedia.org/wiki/Blog"&gt;blogs&lt;/a&gt;, qui permettaient de raconter sa vie&lt;br /&gt; passionnante de tous les jours, puis maintenant il y a &lt;a href="http://twitter.com"&gt;Twitter&lt;/a&gt;, qui force de&lt;br /&gt;résumer sa vie passionnante en 140 caractères.&lt;br /&gt;&lt;br /&gt;Comme je n'ai pas une vie passionnante, 140 caractères sont longtemps suffisant pour expliquer que je vais au travail, je suis bloqué sur un problème en PHP, j'ai vu un site super, j'ai mangé au Delectis à midi et que "Tien, c'est déjà 16h30 alors je vais rentrer".&lt;br /&gt;&lt;br /&gt;Donc je vous invite tous à retrouver le fil RSS de ma vie &lt;a href="http://twitter.com/killerwhile"&gt;La vie au format RSS de Benoit Perroud&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5892447238518830616?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5892447238518830616/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5892447238518830616' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5892447238518830616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5892447238518830616'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/12/twitter-un-vrai-service-web-20.html' title='Twitter, un vrai service Web 2.0'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5318218349833973018</id><published>2007-12-15T11:12:00.000+01:00</published><updated>2007-12-15T11:36:42.271+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='self'/><category scheme='http://www.blogger.com/atom/ns#' term='optimisation'/><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><title type='text'>Getting Things Done® (GTD® aussi) : le sydrome du "Ca c'est fait !"</title><content type='html'>Un mot très en vogue en ce moment (cf Google trend sur &lt;a style="font-style: italic;" href="http://www.google.com/trends?q=gtd"&gt;getting things done&lt;/a&gt;), GTD® est une méthodologie d'organisation des tâches quotidiennes à accomplir. Dévoilée dans un livre écrit par David Allen publié en 2001, &lt;b&gt;Getting Things Done®, &lt;i&gt;the art of stress-free productivity&lt;/i&gt;&lt;/b&gt;, elle reprend un certain nombre de choses connues en matière de gestion du temps mais les systématise dans un processus structuré, gage d'efficacité.&lt;br /&gt;&lt;br /&gt;Cette systématique est intéressante car elle peut nous faire prendre conscience de la méthodologie que peut-être certain utilisaient déjà et ainsi nous amener à y réfléchir en vue de l'optimiser à nos besoins.&lt;br /&gt;&lt;br /&gt;L'objectif de GTD® est de porter toute la créativité et l'énergie sur la seule action qu'on a délibérément choisi de faire et d'approcher au mieux un état de productivité sans stress annoncé.&lt;br /&gt;&lt;br /&gt;Les 2 concepts mis en exergue par cette théorie sont les suivants  :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Les tâches sont interdépendantes&lt;/li&gt;&lt;li&gt;Les priorités des tâches dépendent d'un contexte&lt;/li&gt;&lt;/ul&gt;Fort de ce constat, GTD® nous donne une systématique pour&lt;br /&gt;&lt;ul&gt;&lt;li&gt;recenser les tâches et les reporter sur des listes par sujet,&lt;/li&gt;&lt;li&gt;identifier celle qui peuvent être exécutées immédiatement et les reporter sur une &lt;span style="font-style: italic;"&gt;TODO list&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;les réaliser dans un ordre de priorité dépendant du contexte (temps à disposition, état de fatigue, endroit, ...).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Une fois la tâche accomplie, GTD® propose une phase de revue durant laquelle la tâche est notée comme faite (le fameux syndrome du "&lt;span style="font-style: italic;"&gt;Ca c'est fait !&lt;/span&gt;", qui n'est en réalité rien qu'un petit vu sur la &lt;span style="font-style: italic;"&gt;TODO list&lt;/span&gt; mais qui procure une satisfaction bien au-delà du consentement, mais là je m'égare...) et le cycle organisationnel peut recommencer.&lt;br /&gt;&lt;br /&gt;GTD® ne propose pas de support spécifique pour la liste des tâches à accomplir (&lt;span style="font-style: italic;"&gt;TODO list&lt;/span&gt;), mais précise que le moyen utilisé doit être fiable.&lt;br /&gt;&lt;br /&gt;Une petite corollaire de GTD® que je trouve intéressantes est que &lt;span style="font-weight: bold;"&gt;les tâches prenant moins de 2 minutes sont faites immédiatement&lt;/span&gt;. Car "&lt;span style="font-style: italic;"&gt;moins de 2 minutes&lt;/span&gt;" est à peu près le temps pris pour la gestion organisationnelle de la tâche.&lt;br /&gt;&lt;br /&gt;Pour ceux qui comme moi pensent que la curiosité n'est pas toujours un vilain défaut :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://www.davidco.com/what_is_gtd.php&lt;/li&gt;&lt;li&gt;http://fr.wikipedia.org/wiki/Getting_Things_Done&lt;/li&gt;&lt;li&gt;http://wiki.43folders.com/index.php/Productivity_pr0n&lt;/li&gt;&lt;/ul&gt;Getting Things Done® et GTD® sont des marques déposées depuis 2005.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5318218349833973018?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5318218349833973018/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5318218349833973018' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5318218349833973018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5318218349833973018'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/12/getting-things-done-gtd-aussi-le.html' title='Getting Things Done® (GTD® aussi) : le sydrome du &quot;&lt;i&gt;Ca c&apos;est fait !&lt;/i&gt;&quot;'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-6561538767886524849</id><published>2007-12-09T22:50:00.000+01:00</published><updated>2007-12-11T14:38:38.456+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='optimisation'/><category scheme='http://www.blogger.com/atom/ns#' term='md5'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>60 millions de hashes md5 !</title><content type='html'>Sur mon &lt;span style="font-style: italic;"&gt;petit&lt;/span&gt; projet de &lt;a href="http://md5.noisette.ch/"&gt;revserse md5 lookup database&lt;/a&gt;, je viens de dépasser les 60'000'000 de hashes md5 dans la base de données interne, qui fait maintenant 4.2 GB.&lt;br /&gt;&lt;br /&gt;En gros j'ai introduit dans la base tous les hashes de 4 lettres composés des caractères a-z, A-Z, 0-9, ., -, _, !, $, *, %, &amp;amp;, /, (, ), =, ?, #, @, +, ", [, ], {, }, et tous les hashes de 5 lettres composés de caractères a-z.&lt;br /&gt;&lt;br /&gt;On remarque que sur l'échantillon généré les hashes sont bien uniformément répartis, mais on a une préférence non significative pour les hashes commençant pas 0x46.&lt;br /&gt;&lt;br /&gt;La prochaine étape est les hashes de 5 à 7 lettres composés des caractéres a-z et 0-9, ce qui nous fait ~80'000'000'000 de hashes supplémentaires...&lt;br /&gt;Ensuite je prendrais les dictionnaires Openoffice afin de générer les hashes de mots existants.&lt;br /&gt;&lt;br /&gt;Happy &lt;a href="http://md5.noisette.ch"&gt;md5 cracking sur md5.noisette.ch&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-6561538767886524849?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/6561538767886524849/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=6561538767886524849' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6561538767886524849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6561538767886524849'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/12/60-millions-de-hashes-md5.html' title='60 millions de hashes md5 !'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2154299940779406557</id><published>2007-11-25T21:00:00.000+01:00</published><updated>2007-11-28T11:21:45.928+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Fonction url_get_contents en PHP</title><content type='html'>Plutôt que d'utiliser un bien moche &lt;span style="font-style: italic;"&gt;file_get_contents($url)&lt;/span&gt; où &lt;span style="font-style: italic;"&gt;$url&lt;/span&gt; est une &lt;a href="http://fr.wikipedia.org/wiki/URL"&gt;url&lt;/a&gt;, je vous propose une petite fonction &lt;span style="font-weight: bold;"&gt;url_get_contents($url)&lt;/span&gt; utilisant l'extension &lt;a href="http://www.php.net/curl"&gt;curl&lt;/a&gt; de PHP qui permet aussi bien de télécharger le contenu d'une url via &lt;span style="font-style: italic;"&gt;GET&lt;/span&gt; que &lt;span style="font-style: italic;"&gt;POST&lt;/span&gt; :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;function url_get_contents($url, $post = null) {&lt;br /&gt; $curl = curl_init();&lt;br /&gt; curl_setopt ($curl, CURLOPT_URL, $url);&lt;br /&gt; curl_setopt ($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);&lt;br /&gt; curl_setopt ($curl, CURLOPT_HEADER, 0);&lt;br /&gt; curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);&lt;br /&gt; curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, 0);&lt;br /&gt; //curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1); // if no safe_mode neither open_basedir&lt;br /&gt;&lt;br /&gt; if (is_array($post)) {&lt;br /&gt;     curl_setopt ($curl, CURLOPT_POST, 1);&lt;br /&gt;     curl_setopt ($curl, CURLOPT_POSTFIELDS, $post);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; $html = curl_exec ($curl);&lt;br /&gt; curl_close ($curl);&lt;br /&gt; return $html;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;L'utilisation est réellement simple :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$content = url_get_contents('http://www.noisette.ch');&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2154299940779406557?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2154299940779406557/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2154299940779406557' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2154299940779406557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2154299940779406557'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/11/fonction-urlgetcontents-en-php.html' title='Fonction url_get_contents en PHP'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-6467774741195697697</id><published>2007-11-25T20:48:00.000+01:00</published><updated>2007-11-25T20:59:39.239+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Reverse MD5 databases aggregator</title><content type='html'>J'écrivais il y a à peu près une année un message à propos  des &lt;a href="http://benoitperroud.blogspot.com/2006/12/reverse-md5.html"&gt;reverses MD5&lt;/a&gt; et de la problématique que ces bases de données posent.&lt;br /&gt;Suite à un message au sujet de l'utilisation de &lt;a href="http://www.lightbluetouchpaper.org/2007/11/16/google-as-a-password-cracker/"&gt;Google comme base de données de hash&lt;/a&gt; (en anglais), j'ai remis à jour mon &lt;a href="http://md5.noisette.ch/"&gt;aggrégateur de revse MD5&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Il questionne maintenant pas moins de 8 bases de données en plus de sa base de données propre, et permet maintenant de recevoir un mail quand le hash est trouvé après-coup.&lt;br /&gt;&lt;br /&gt;Une petite API est disponible pour intégrer le service dans vos propres applications, notemment pour déterminer si un mot de passe sera crackable en &lt;span style="font-style: italic;"&gt;O(1)&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Happy &lt;/span&gt;&lt;a href="http://md5.noisette.ch"&gt;&lt;span style="font-style: italic;"&gt;md5 cracking&lt;/span&gt; sur md5.noisette.ch&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-6467774741195697697?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/6467774741195697697/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=6467774741195697697' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6467774741195697697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6467774741195697697'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/11/reverse-md5-databases-aggregator.html' title='Reverse MD5 databases aggregator'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-4724931906203686228</id><published>2007-10-09T17:26:00.000+02:00</published><updated>2007-10-09T15:26:59.931+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smtp'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Contourner le blocage du port SMTP</title><content type='html'>Votre provider bloque le port tcp/25 (SMTP) et donc vous ne pouvez pas envoyer de mails via votre serveur mail préféré ?&lt;br /&gt;&lt;br /&gt;Une solution toute simple mais qui nécessite d'avoir un compte shell sur un serveur quelconque (qui peut être votre ordinateur local), qu'on va nommer &lt;span style="font-style: italic;"&gt;srv_shell&lt;/span&gt; dans cet exemple, est de faire un tunnel entre votre ordinateur local, le &lt;span style="font-style: italic;"&gt;srv_shell&lt;/span&gt; et votre serveur de mail préféré, appelé &lt;span style="font-style: italic;"&gt;srv_mail&lt;/span&gt; ici.&lt;br /&gt;&lt;br /&gt;La commande à exécuter sur votre ordinateur local est la suivante :&lt;br /&gt;&lt;blockquote&gt;ssh -NL 2525:&lt;span style="font-style: italic;"&gt;srv_mail&lt;/span&gt;:25 user@&lt;span style="font-style: italic;"&gt;srv_shell&lt;/span&gt;&lt;/blockquote&gt;L'utilisation d'un clé ssh est encouragée.&lt;br /&gt;&lt;br /&gt;Ensuite dans votre logiciel d'envoi de mail préféré il suffit de spécifier comme serveur sortant &lt;span style="font-style: italic;"&gt;localhost&lt;/span&gt; sur le port 2525.&lt;br /&gt;&lt;br /&gt;Et hop la sécurité le côté ennuyeux à ce type de sécurité mis en place par l'administrateur est &lt;span style="font-style: italic;"&gt;bypassé&lt;/span&gt;. J'y reviendrai d'ailleurs dans un autre article, car il m'est arrivé récemment ce genre de mésaventure : ip fixe avec serveur Exchange + &lt;a href="http://en.wikipedia.org/wiki/Storm_Worm"&gt;Storm Worm&lt;/a&gt; = blacklistage de l'ip...&lt;br /&gt;&lt;br /&gt;Une deuxième solution pourrait venir à l'esprit si on possède son propre serveur dédié, mais je vais expliquer pourquoi cette solution est à bannir au plus vite.&lt;br /&gt;&lt;br /&gt;La deuxième idée est d'utiliser un logiciel comme &lt;a href="http://www.boutell.com/rinetd/"&gt;rinetd&lt;/a&gt; ou &lt;a href="http://sammy.net/%7Esammy/hacks/"&gt;redir&lt;/a&gt;, qui ont pour but de rediriger le traffic adressé à un port vers un autre. Donc tout ce qui arriverait sur le port 2525 de &lt;span style="font-style: italic;"&gt;srv_shell&lt;/span&gt; serait redirigé vers le port 25 du &lt;span style="font-style: italic;"&gt;srv_mail&lt;/span&gt;. Le problème de cette solution est quand les deux serveurs &lt;span style="font-style: italic;"&gt;srv_shell&lt;/span&gt; et &lt;span style="font-style: italic;"&gt;srv_mail&lt;/span&gt; sont les mêmes, la connexion sur le port 25 est redirigé par la même machine, le service mail va donc recevoir une connexion depuis &lt;span style="font-style: italic;"&gt;localhost.&lt;/span&gt; Et comme la très grande majorité des services mails sont configurés pour que &lt;span style="font-style: italic;"&gt;localhost&lt;/span&gt; puisse envoyer sans restrictions des mails, cette configuration ouvre un &lt;span style="font-style: italic;"&gt;open-relay&lt;/span&gt;. Quiconque trouve ce port 2525 sur votre serveur pourra l'utilisé pour spammer le monde entier -&gt; la redirection de port sur un serveur mail est donc à bannir.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-4724931906203686228?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/4724931906203686228/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=4724931906203686228' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4724931906203686228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4724931906203686228'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/09/contourner-le-blocage-du-port-smtp.html' title='Contourner le blocage du port SMTP'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-7207308608831523505</id><published>2007-10-08T14:09:00.000+02:00</published><updated>2007-10-15T12:02:19.253+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Création manuelle d'un botnet "localisé"</title><content type='html'>Une méchante idée m'est venue en lisant un article de Slashdot : &lt;a href="http://it.slashdot.org/article.pl?sid=07/10/05/1234217"&gt;Cracked Linux Boxes Used to Wield Windows Botnets&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Afin de se composer un réseau de botnets, il serait extrêmement simple à une personne malveillante de vendre des routers ADSL modifiés (rootkités) sur des sites comme Ebay ou Ricardo en Suisse. L'utilisation pour l'acheteur pourrait être strictement similaire, au point qu'il ne se douterait pas que quelqu'un d'autre à la main sur son nouveau routeur.&lt;br /&gt;&lt;br /&gt;Dans cet ordre d'idée, on voit de plus en plus de router ADSL se faire rootkiter à la suite d'un piratage d'un ordinateur. La raison principale : un mot de passe par défaut... Idem pour les connexions wireless : on la casse (l'histoire d'une journée pour du WEP avec du matériel correct) avant de s'attaquer au router !&lt;br /&gt;&lt;br /&gt;En résumé, il serait presque rentable de se monter un botnet "localisé" et persistant, car placé dans des endroits stratégiques.&lt;br /&gt;&lt;br /&gt;Deux petites recommandations pour éviter toutes mauvaises surprises : TOUJOURS modifier le mot de passe de vos routeurs (quitte à le noter dessous, le pirates devant hacker votre webcam et le robot téléguidé du petit frère pour réussir à placer le mot de passe dans le champs de vision de la webcam), et abandonner les connexions wireless...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-7207308608831523505?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/7207308608831523505/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=7207308608831523505' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7207308608831523505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7207308608831523505'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/10/cration-manuelle-dun-botnet-localis.html' title='Création manuelle d&apos;un botnet &quot;localisé&quot;'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-1291955422160506416</id><published>2007-09-28T07:14:00.000+02:00</published><updated>2007-09-28T07:17:03.768+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>La surjection, nouvelle maladie ?</title><content type='html'>La prochaine fois que vous allez chez le médecin, dites-lui que vous souffrez d'une &lt;span style="font-weight:bold;"&gt;surjection&lt;/span&gt; et que je avez besoin d'un &lt;span style="font-weight:bold;"&gt;injection&lt;/span&gt; pour retrouver un état stable de &lt;span style="font-weight:bold;"&gt;bijection&lt;/span&gt;...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-1291955422160506416?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/1291955422160506416/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=1291955422160506416' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1291955422160506416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1291955422160506416'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/09/la-surjection-nouvelle-maladie.html' title='La surjection, nouvelle maladie ?'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2926216083440841745</id><published>2007-09-24T19:35:00.000+02:00</published><updated>2007-09-24T17:37:01.542+02:00</updated><title type='text'>Implémentation paresseuse du "Visitor pattern" en PHP</title><content type='html'>Sans m'étendre sur les bienfaits du &lt;a style="font-style: italic;" href="http://en.wikipedia.org/wiki/Visitor_pattern"&gt;Visitor pattern&lt;/a&gt;, dont le but est de séparer un algorithme de sa structure de données, je souhaite proposer ici une implémentation paresseuse mais possible en PHP.&lt;br /&gt;&lt;br /&gt;En théorie ce pattern repose sur 2 interfaces qui permettent de faire un &lt;span style="font-style: italic;"&gt;double dispatch&lt;/span&gt; (appeler depuis un objets &lt;span style="font-style: italic;"&gt;visitable&lt;/span&gt; la fonction lui correspondant dans le visiteur) :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Visitable&lt;/span&gt; qui contient une fonction &lt;span style="font-style: italic;"&gt;apply(Visitor $v)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic;"&gt;Visitor&lt;/span&gt; qui contient une fonction &lt;span style="font-style: italic;"&gt;visit(Visitable $v)&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Puisqu'en PHP il n'est pas possible de faire de la surcharge de paramètres de fonction (polymorphisme), il faut donc appeler les fonctions différemment selon les types de structure de données.&lt;br /&gt;&lt;br /&gt;En Java :&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="font-style: italic;"&gt;interface Visitor {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    void visit(Wheel wheel);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    void visit(Engine engine);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    void visit(Body body);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    void visit(Car car);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;abstract class Visitable {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    void apply(Visitor visitor) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;        visitor.apply(this);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;En PHP :&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="font-style: italic;"&gt;interface Visitor {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    public function visitWheel($wheel);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    public function visitEngine($engine);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    public function visitBody($body);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    public function visitCar($car);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;interface Visitable {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    public function apply(Visitor $visitor);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;On remarque donc qu'en PHP on devra réécrire toutes les fonctions &lt;span style="font-style: italic;"&gt;apply&lt;/span&gt; pour qu'elles appellent la fonction &lt;span style="font-style: italic;"&gt;visit___&lt;/span&gt; correspondant à leur type.&lt;br /&gt;Mais paresseux comme je suis, la redéfinition de la fonction &lt;span style="font-style: italic;"&gt;apply&lt;/span&gt; pour chaque &lt;span style="font-style: italic;"&gt;visitable&lt;/span&gt; me parait un tâche trop répétitive et ennuyeuse. L'idée sous-jacente est de faire un &lt;span style="font-style: italic;"&gt;dispatch&lt;/span&gt; dynamique en fonction du type du &lt;span style="font-style: italic;"&gt;visitable,&lt;/span&gt; de la façon suivante :&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span style="font-style: italic;"&gt;abstract class Visitable {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    public function visit(Visitable $visitable)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;        $func = array(&amp;amp;$this, 'visit' . get_class($visitable));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;        if (!is_callable($func)) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;            trigger_error('[' . get_class($this) . '] Class ' . get_class($this) . ' has no visit' . get_class($visitable) . ' function', E_USER_ERROR);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;        call_user_func($func, $visitable);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;Ainsi le visiteur devrait implémenter les fonctions standards &lt;span style="font-style: italic;"&gt;visitWheel&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;visitEngine&lt;/span&gt;, ... mais leur &lt;span style="font-style: italic;"&gt;dispatching&lt;/span&gt; devient automatique !&lt;br /&gt;&lt;br /&gt;Mis à part la lourdeur de la fonction &lt;span style="font-style: italic;"&gt;call_user_func&lt;/span&gt;, le reste de cette implémentation dynamique reste intéressante.&lt;br /&gt;&lt;br /&gt;Références :&lt;br /&gt;http://en.wikipedia.org/wiki/Visitor_pattern&lt;br /&gt;http://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_is_more_than_function_overloading&lt;br /&gt;&lt;br /&gt;Plus d'information pour les intéressés :&lt;br /&gt;http://www.polyglotinc.com/reflection.html&lt;br /&gt;http://www.javaworld.com/javaworld/javatips/jw-javatip98.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2926216083440841745?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2926216083440841745/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2926216083440841745' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2926216083440841745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2926216083440841745'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/09/implmentation-paresseuse-du-visitor.html' title='Implémentation paresseuse du &quot;Visitor pattern&quot; en PHP'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-7335595726214519437</id><published>2007-09-18T14:58:00.000+02:00</published><updated>2007-09-25T07:02:50.435+02:00</updated><title type='text'>Offre d'emploi : customer care</title><content type='html'>Ma petite startup, leader en suisse romande sur le marché des &lt;a href="http://www.migtechnology.ch/"&gt;logiciels immobiliers&lt;/a&gt;, recherche un nouveau collaborateur afin d'assurer le support technique et la formation de ses  nombreux clients.&lt;br /&gt;&lt;br /&gt;Plus concrètement, le poste consisterait à répondre par téléphone/email aux questions techniques et d'assurer la formation des nouveaux clients sur les logiciels.&lt;br /&gt;&lt;br /&gt;Le profile recherché est le suivant :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Langue maternelle française, bon niveau en allemand un plus&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Excellentes capacités en communication, autant orales qu'écrites&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Bonne capacité à comprendre et résoudre les problèmes&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Capacité de travailler sur plusieurs tâches en parallèle&lt;/li&gt;&lt;li&gt;Bonne compréhension de l'architecture client-serveur&lt;/li&gt;&lt;/ul&gt;Les postulations peuvent être directement adressées à info _A_T_ migtechnology _P_O_I_N_T_ ch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-7335595726214519437?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/7335595726214519437/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=7335595726214519437' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7335595726214519437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7335595726214519437'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/09/offre-demploi-customer-care.html' title='Offre d&apos;emploi : customer care'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-8126508244992833614</id><published>2007-09-16T16:57:00.000+02:00</published><updated>2007-09-16T17:16:10.457+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Algue? piézo-phosphorescente</title><content type='html'>Mercredi 12 septembre 2007, tard le soir, plage de Vieux-boucaux dans les Landes française.&lt;br /&gt;&lt;br /&gt;Nous étions alors en vacances entre amis. Une soirée des plus tranquilles, avec comme il se doit un passage sur la plage pour boire quelque breuvage local. Cadre peu crédible pour la suite de l'histoire si nous n'avions pas été 9 à être témoin du phénomène que nous avons découvert ce soir-là.&lt;br /&gt;&lt;br /&gt;C'est en s'approchant de l'océan qu'on aperçut des points lumineux autour de nos pas. Des points d'une légère lumière bleutée s'illuminaient à chaque pression de nos pieds sur le sol dans un rayon d'une vingtaine de centimètres, avant de disparaitre 3 secondes plus tard.&lt;br /&gt;Phénomène qui nous a émerveillé une bonne partie de la soirée, mais qui reste un mystère pour nos esprits curieux...&lt;br /&gt;&lt;br /&gt;Une hypothèse d'une algue ou d'un organisme piézo-phosphorescent est de mise, car les points de couleurs apparaissaient dans une zone semblable à la zone de compression imposée par nos pas...&lt;br /&gt;&lt;br /&gt;Mais les hypothèses les plus folles ont été imaginées sous cette nuit claire et chargée d'étoiles filantes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-8126508244992833614?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/8126508244992833614/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=8126508244992833614' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8126508244992833614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8126508244992833614'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/09/algue-pizo-phosphorescente.html' title='Algue? piézo-phosphorescente'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-934666462891034466</id><published>2007-08-20T22:01:00.000+02:00</published><updated>2007-08-27T10:15:56.802+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thumbshot'/><category scheme='http://www.blogger.com/atom/ns#' term='snapshot'/><title type='text'>Générateur automatique de visualisation de site</title><content type='html'>Un nom qui ne donne pas très bien en français, mais j'ai développé avec une petite équipe un générateur automatique de visualisation de site.&lt;br /&gt;&lt;br /&gt;Le principe est simple : on donne une url au générateur qui nous retourne une image qui est une copie d'écran du site qu'on aurait eu dans notre navigateur. Le coeur du générateur utilise le moteur &lt;a href="http://developer.mozilla.org/fr/docs/Gecko"&gt;Gecko&lt;/a&gt; pour le rendu de la page web.&lt;br /&gt;&lt;br /&gt;Une démo du &lt;a href="http://www.mythumbshot.com/"&gt;service de génération de visualisation de site&lt;/a&gt; est disponible en ligne, et l'idée est de développer une puissant API pour interfacer le service. L'idée principale de l'API est d'utiliser une url de callback qui permettra au service directement de retourner l'image une fois générée afin d'éviter au client de devoir poller pour controler si l'image est créée ou pas.&lt;br /&gt;&lt;br /&gt;Les possibilités du service sont les suivantes :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Taille des images paramétrables (120x90, 160x120, 320x240, 640x480, 1024x768)&lt;/li&gt;&lt;li&gt;Format d'image JPEG ou PNG&lt;/li&gt;&lt;li&gt;Ajout de délai avant la capture (pour les sites en flash par exemple)&lt;/li&gt;&lt;li&gt;Mise-à-jour hebdomadaire, mensuelle ou annuelle des captures&lt;/li&gt;&lt;/ul&gt;Les feedbacks sont bien évidemment encouragés, et d'autres news sur l'API &amp;amp; CO suivront.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-934666462891034466?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/934666462891034466/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=934666462891034466' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/934666462891034466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/934666462891034466'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/08/gnrateur-automatique-de-visualisation.html' title='Générateur automatique de visualisation de site'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-1887354607925926135</id><published>2007-08-16T13:07:00.000+02:00</published><updated>2007-08-16T14:25:20.310+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='optimisation'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Uniqid ou la contre-intuitivité des arguments</title><content type='html'>D'après le manuel PHP,&lt;a href="http://ch2.php.net/uniqid"&gt;&lt;/a&gt; le prototype de la fonction  &lt;a href="http://ch2.php.net/uniqid"&gt;uniqid&lt;/a&gt; est le suivant :&lt;br /&gt;&lt;blockquote&gt;string &lt;b&gt;uniqid&lt;/b&gt; ( [string prefix [, bool more_entropy]] )&lt;/blockquote&gt;Le deuxième paramètre à l'air réellement intéressant, dans la mesure où il assure une meilleure unicité de la chaine produite. Une propriété qui de toute évidence nous intéresse si on utilise cette fonction uniqid.&lt;br /&gt;&lt;p&gt;Sans s'étendre sur la probabilité de collision entre les 2 appels (ce que j'étendrai plus longuement dans un autre article), je voulais juste montrer la différence de vitesse d'exécution qu'induisait ce paramètre &lt;span style="font-style: italic;"&gt;more_entropy&lt;/span&gt;. Un petit script faisant 100 appels à uniqid avec une valeur possible du paramètre, nous donne le résultat suivant (!) :&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;100 * uniquid(mt_rand()) en 0.799283981323 seconde&lt;/p&gt;&lt;p&gt;100 * uniquid(mt_rand(), true) en 0.00346183776855 seconde&lt;/p&gt;&lt;/blockquote&gt;Chose extrêmement intéressante, le temps d'exécution de la fonction est 3 ordres de grandeurs en dessous si on demande une meilleures unicité du résultat.&lt;br /&gt;&lt;br /&gt;La question obligée est donc : pourquoi est-ce que cette fonctionne ne prend pas par défaut cette option, puisqu'elle a tous les avantages (meilleures résultats, plus rapide) ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-1887354607925926135?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/1887354607925926135/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=1887354607925926135' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1887354607925926135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1887354607925926135'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/08/uniqid-ou-la-contre-intuitivit-des.html' title='Uniqid ou la contre-intuitivité des arguments'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-3212157144348569790</id><published>2007-08-13T09:20:00.000+02:00</published><updated>2007-08-13T14:57:57.070+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>Types ENUM avec MySQL</title><content type='html'>Toujours en train de travailler avec MySQL, et encore pour un bon moment, voici une particularité du type &lt;span style="font-style: italic;"&gt;enum&lt;/span&gt; :&lt;br /&gt;&lt;br /&gt;Soit un champ field2 :&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;`field2` enum('0','1') NOT NULL default '0'&lt;/blockquote&gt;Soit une requête :&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;SELECT * FROM ... WHERE ... AND field2 = 1&lt;/blockquote&gt;Le résultat de cette requête est intéressant dans le sens où MySQL va sélectionner tous les tuples dont la valeur du champ &lt;span style="font-style: italic;"&gt;field2&lt;/span&gt; vaut '0'. Pourquoi cela ? Parce qu'en passant le 1 sous forme d'entier, MySQL va l'associer à la première valeur de l'énumération, '0' donc. Dans le même ordre d'idée &lt;span style="font-style: italic;"&gt;WHERE ... AND field2 = 2&lt;/span&gt; sélectionnera tous les tuples dont &lt;span style="font-style: italic;"&gt;field2&lt;/span&gt; vaut '1'.&lt;br /&gt;&lt;br /&gt;La requête&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;SELECT * FROM ... WHERE ... AND field2 = '1'&lt;/blockquote&gt;fournira quant à elle la juste réponse. Attention donc avec les types des valeurs, surtout en PHP...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-3212157144348569790?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/3212157144348569790/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=3212157144348569790' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3212157144348569790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3212157144348569790'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/08/types-enum-avec-mysql.html' title='Types ENUM avec MySQL'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-1537999078058280184</id><published>2007-08-06T12:51:00.000+02:00</published><updated>2007-08-06T13:12:24.997+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>Mysql NT vs Unix : quand les systèmes de fichier font des différences</title><content type='html'>La question posée ici est la suivante : le nom des tables dans une base de données MySQL est-il sensible à la casse ou pas ?&lt;br /&gt;&lt;br /&gt;La réponse dépend du système sur lequel le serveur tourne... Et cette différence vient même d'une manière plus intrinsèque du système de fichier sur lequel repose la base de données.&lt;br /&gt;&lt;br /&gt;Explication :&lt;br /&gt;&lt;br /&gt;Pour MySQL, une base de données est un répertoire du même nom dans lequel se trouvent des fichiers représentant les tables. Le nom des fichiers est naturellement identique aux tables, à l'extension prêt.&lt;br /&gt;&lt;br /&gt;Pour savoir sur une base existe, MySQL va chercher si le répertoire correspondant existe. Du même principe pour accéder à un table il va ouvrir le fichier lié.&lt;br /&gt;&lt;br /&gt;Sur un système de fichier Unix, ext3 ou reiserfs par exemple, un fichier &lt;span style="font-style: italic;"&gt;base1/table1.MYI&lt;/span&gt; n'est pas le même que &lt;span style="font-style: italic;"&gt;base1/tAbLe1.MYI&lt;/span&gt;, donc une requête "&lt;span style="font-style: italic;"&gt;SELECT * FROM table1&lt;/span&gt;" ou "&lt;span style="font-style: italic;"&gt;SELECT * FROM tAbLe1&lt;/span&gt;" ne produira pas le même résultat. Sur un système de fichier NTFS par contre, les chemins ci-dessus pointeront vers le même fichier, et donc les 2 requêtes précédents fonctionneront.&lt;br /&gt;&lt;br /&gt;En conclusion, le nom des bases et tables MySQL sont sensibles à la casse sur un système Unix, et non sensible à la casse sur un système Windows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-1537999078058280184?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/1537999078058280184/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=1537999078058280184' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1537999078058280184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1537999078058280184'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/08/mysql-nt-vs-unix-quand-les-systmes-de.html' title='Mysql NT vs Unix : quand les systèmes de fichier font des différences'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-3504420172563486680</id><published>2007-05-14T09:21:00.000+02:00</published><updated>2007-05-14T07:59:14.422+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Citer Montaigne quand on parle d'informatique</title><content type='html'>Chose pas forcément aisée, mais Jean Véronis, professeur de linguistique et d'informatique à l'université de Montpellier y est parvenu à merveille jeudi 18 janvier, dans la capsule de Monsieur Pain.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://info.rsr.ch/fr/rsr.html?siteSect=1011&amp;sid=7442246&amp;amp;cKey=1169108013000&amp;bcItemName=capsule_multimedia&amp;amp;broadcastId=475027&amp;broadcastItemId=7425419&amp;amp;rubricId=3500&amp;programId=110451&amp;amp;bcItemName=capsule_multimedia"&gt;"Scrobbler" Tome II, jeudi 18 janvier 2007&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;La capsule, une émission à écouter et ré-écouter...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-3504420172563486680?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3504420172563486680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3504420172563486680'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/05/citer-montaigne-quand-on-parle.html' title='Citer Montaigne quand on parle d&apos;informatique'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-3177280274539815340</id><published>2007-04-06T13:27:00.000+02:00</published><updated>2007-04-21T11:37:35.191+02:00</updated><title type='text'>Je sers mon pays...</title><content type='html'>Joyeuses Pâques !&lt;br /&gt;&lt;br /&gt;Pendant que les uns vont profiter du climats printanier annoncé pour ce week-end de Pâques, d'autres remplissent leurs obligations de citoyens en gardant un parc véhicule (4 piranha 8x8, 3 eagles et quelques duros) ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-3177280274539815340?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/3177280274539815340/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=3177280274539815340' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3177280274539815340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3177280274539815340'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/04/je-sers-mon-pays.html' title='Je sers mon pays...'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-3719952432286061694</id><published>2007-04-06T12:43:00.000+02:00</published><updated>2007-04-21T11:42:47.088+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='epfl'/><title type='text'>Un ingénieur, un vrai</title><content type='html'>Samedi 31 mars a eu lieu la cérémonie de remise des diplômes : la Magistrale. Très belle cérémonie, en collaboration avec le cirque StarLight qui animaient les pauses inter-discours. Même &lt;a href="http://en.wikipedia.org/wiki/Paul_Allen"&gt;Paul Allen&lt;/a&gt; était présent et serrait la main de tous les nouveaux ingénieurs. Non là je fabule un peu sur la poignée de main, mais Paul était bien présent et nous a fait un discours de 40 minutes. Une &lt;a href="http://mediatheque.epfl.ch/modules.php?include=view_album.php&amp;file=index&amp;amp;name=gallery&amp;op=modload&amp;amp;set_albumName=albuo59"&gt;galerie de photo de la Magistrale 2007&lt;/a&gt; est disponible.&lt;br /&gt;&lt;br /&gt;Puis fut le temps de la remise des diplômes, donc du passage sur scène et de la photo de la volée "Master in Computer Science Printemps 2007".&lt;br /&gt;&lt;br /&gt;Et petite cerise sur le gâteau, qui est aussi l'aboutissement du travail régulier que j'ai fourni tout au long de mon travail de Master, j'ai reçu le prix de la Société Suisse des entreprises en qualité de deuxième meilleure moyenne du cycle Master de la faculté d'Informatique. Voilà une ligne de plus à ajouter à mon CV :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-3719952432286061694?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/3719952432286061694/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=3719952432286061694' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3719952432286061694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3719952432286061694'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/04/un-ingnieur-un-vrai.html' title='Un ingénieur, un vrai'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5328503915130204521</id><published>2007-03-31T12:53:00.000+02:00</published><updated>2007-04-06T12:56:11.492+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Camp de ski avec l'école primaire de Prez-vers-Noréaz</title><content type='html'>La semaine du 26 au 30 mars 2007 a eu lieu le camp de ski de l'école primaire de Prez-vers-Noréaz à Villars-sur-Ollon. Une semaine magnifique retransmise en mots et en images sur le site de &lt;a href="http://ecole.prez-vers-noreaz.ch/"&gt;l'école de Prez-vers-Noréaz&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5328503915130204521?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5328503915130204521/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5328503915130204521' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5328503915130204521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5328503915130204521'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/03/camp-de-ski-avec-lcole-primaire-de-prez.html' title='Camp de ski avec l&apos;école primaire de Prez-vers-Noréaz'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-235006280368474132</id><published>2007-03-13T09:31:00.000+01:00</published><updated>2007-03-13T09:36:10.342+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='epfl'/><title type='text'>Travail de Master : quelques chiffres (suite)</title><content type='html'>Quelques chiffres supplémentaires pour mon travail et mon Master en général :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Note finale du travail de Master : 6 (sur 6 donc :))&lt;/li&gt;&lt;li&gt;Moyenne de Master (sur 93 crédits) : 5.79&lt;/li&gt;&lt;li&gt;Et pas une note en dessous de 5.&lt;/li&gt;&lt;/ul&gt;Je tenais juste à remercier &lt;a href="http://www.ouups.net/"&gt;Marius Erni&lt;/a&gt;, Dominique Bongard et Samuel Gmehlin grâce à qui j'ai réussi à me surpasser durant ces presque 2 ans de Master.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-235006280368474132?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/235006280368474132/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=235006280368474132' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/235006280368474132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/235006280368474132'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/03/travail-de-master-quelques-chiffres.html' title='Travail de Master : quelques chiffres (suite)'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-4030542406231631325</id><published>2007-02-24T09:17:00.000+01:00</published><updated>2007-03-13T09:30:33.337+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Bon anniversaire !</title><content type='html'>Avec pas mal de retard, hop une année de plus. Ca me fait maintenant 20 ans et 6 ans d'expérience :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-4030542406231631325?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/4030542406231631325/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=4030542406231631325' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4030542406231631325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4030542406231631325'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/02/bon-anniversaire.html' title='Bon anniversaire !'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5077987000781002257</id><published>2007-02-22T09:21:00.000+01:00</published><updated>2007-02-25T16:06:36.403+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='epfl'/><title type='text'>Travail de Master : quelques chiffres</title><content type='html'>Rendu vendredi 16 février 2007 à 11h10 et défendu le vendredi suivant, soit le 23 février à 10h30, voici quelques chiffres au sujet de mon travail de Master :&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Analyse et ingénierie inverse de récepteur satellite &lt;span style="font-style:italic;"&gt;Free-To-Air&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Le projet se déroulait sur 24 semaines, donc 120 jours. Retranchés des 8 jours de vacances dont j'ai pu jouir, ça nous fait &lt;span style="font-weight:bold;"&gt;112 jours de travail effectif&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Au final un rapport de 70 pages, 17'426 mots pour 109'036 caractères, et une présentation de 45 minutes supportée par 44 slides encouragé par 300 visites de mon superviseur. &lt;br /&gt;&lt;br /&gt;Mon projet c'est aussi 10'000 lignes de code réparties dans 4 projets (dont &lt;a href="http://www.datarescue.com/idabase/index.htm"&gt;IDA Pro&lt;/a&gt; et &lt;a href="http://www.mamedev.org/"&gt;Mame&lt;/a&gt;) écrites en 1000 heures de travail grâce à 100 litres de &lt;a href="http://www.cokelightman.ch"&gt;Coca-cola Light&lt;/a&gt;. C'est aussi 200 heures de trajets en voiture, 16'800 km parcourus sur l'autoroute A12 entre Matran et Lausanne-Blécherette, 384 mails envoyés en interne et 1640 mails en externe, donc une moyenne de plus de 27 mails envoyés par jour.&lt;br /&gt;&lt;br /&gt;Tout cela pour un travail dont je suis entièrement satisfait, quant par le cadre de travail offert par l'équipe du CSO Office du groupe Kudelski que par les résultats intéressants que j'ai développés. &lt;br /&gt;&lt;br /&gt;Et bien entendu la note finale que je vous laisse deviner reflète la qualité du travail :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5077987000781002257?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5077987000781002257/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5077987000781002257' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5077987000781002257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5077987000781002257'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/02/travail-de-master-quelques-chiffres.html' title='Travail de Master : quelques chiffres'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-4771205968734186520</id><published>2007-02-14T12:50:00.000+01:00</published><updated>2007-02-14T12:54:41.290+01:00</updated><title type='text'>Article de L'Objectif</title><content type='html'>Je suis dans le journal L'Objectif paru vendredi 9 février 2007. Je vous laisse découvrir l'article, en précisant que les noms correspondant à la photo sont faux. Il ne s'agit pas de Frédéric Neukomm derrière à gauche, mais bien Miguel Egger, un employé.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_9jdtZI7diwk/RdL3rHddCjI/AAAAAAAAAAY/SY-FSwXLIE4/s1600-h/objectif_09.02.2007.jpg"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_9jdtZI7diwk/RdL3rHddCjI/AAAAAAAAAAY/SY-FSwXLIE4/s400/objectif_09.02.2007.jpg" alt="" id="BLOGGER_PHOTO_ID_5031356053835287090" border="0" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-4771205968734186520?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/4771205968734186520/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=4771205968734186520' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4771205968734186520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4771205968734186520'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/02/article-de-lobjectif.html' title='Article de L&apos;Objectif'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_9jdtZI7diwk/RdL3rHddCjI/AAAAAAAAAAY/SY-FSwXLIE4/s72-c/objectif_09.02.2007.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-8534583527536155963</id><published>2007-02-04T23:56:00.000+01:00</published><updated>2007-02-05T10:29:51.475+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>Digression sur l'incohérence entre les discours et les actions</title><content type='html'>&lt;blockquote&gt;L'argent n'est pas une finalité, mais un moyen.&lt;/blockquote&gt;Cette phrase qui résonne dans ma tête depuis sa rédaction par Tristan Nitot, directeur de Mozilla Europe (voir l'article en question : &lt;a href="http://standblog.org/blog/post/2006/11/03/93114944-les-revenus-du-projet-mozilla-en-question-et-mes-reponses"&gt;les revenus du projet Mozilla&lt;/a&gt;),  est le départ de cette digression sur mon dégout par rapport à la société capitaliste actuelle.&lt;br /&gt;&lt;br /&gt;Quand un projet fonctionne, quel qu'il soit, tout le monde veut sa part du gâteau et en tirer les bénéfices. Les exemples sont nombreux. Ils passent par la Fondation Mozilla (discuté sur un précédent billet : &lt;a href="http://benoitperroud.blogspot.com/2006/12/ryzom-un-mmorpg-dsormais-libre.html"&gt;La liberté a un prix&lt;/a&gt;), ou récemment en discutant avec mon père d'une jeune gymnaste à l'artistique, dotée d'un énorme talent, qui ne trouve pas d'entrainements adaptés à son niveau dans notre canton et qui s'entraine donc ailleurs, et concours maintenant sous les couleurs de cet autre canton. La finalité pour cette gymnaste est sa progression et son épanouissement, où elle s'entraine et qui elle représente n'est qu'une question de gout et de couleurs. La finalité dans cette histoire doit revenir à la jeune fille, et non pas à l'entraineur du club dans lequel par chance elle s'est présentée un jour... Ce genre d'attribution de finalité n'est que trop souvent appliqué. En politique je n'en parle même pas...&lt;br /&gt;&lt;br /&gt;La question devrait plutôt être :&lt;br /&gt;&lt;br /&gt;Quelle est la finalité de mon combat (action, engagement) ? Mon propre confort ou celui des autres, de la société, de celui/celle pour qui je me bats ou de ce pour quoi je me bats ? Est-ce que ça va plus me rapporter à moi qu'à la personne que j'aide ?&lt;br /&gt;&lt;br /&gt;Est-ce que je suis le cheminement "Faites comme je dis et pas comme je fais" (cf les beaux discours sur l'environnement faits par des dirigeants venus en jet privés lors du WEF), ou "C'est l'intention qui compte" ?&lt;br /&gt;&lt;br /&gt;Autant de points qui me révoltent en silence. Autant d'efforts gaspillés par les seuls caprices de gens plus fortunés... J'entendais à la radio un témoignage d'une personne concernant l'éventuelle introduction d'une taxe de circulation au centre de Montreux : "Moi je gagne très bien ma vie, et je me réjouis d'avoir les routes [du centre de Montreux] pour moi tout seul."&lt;br /&gt;Ne comprenez vous pas dans ces propos les fondements même du socialisme ? Le partage des richesses, le cout de la vie en fonction du revenu ? Comment justifier la différence de la proportion de la TVA (de 7.6% chez nous) sur un litre de lait par exemple pour quelqu'un qui gagne 150'000.- par rapport à quelqu'un qui gagne 60'000 ? Tellement d'idée qui sont simplement balayées par des arguments populistes qui dit par exemple "Si vous votez pour nous, nous améliorerons les conditions de vie en limitant le chômage grâce au durcissant la loi sur les étrangers", mais en cachant à la vox populi que ce "nous" fera passer par la même occasion un tarif dégressif des impôts et des avantages fiscaux pour les grandes fortunes. Comment garder un avis objectif, un esprit critique quand la politique passe par du markéting de masse, ne tenant plus compte des idées à défendre mais les moyens mis en place pour la faire passer.&lt;br /&gt;&lt;br /&gt;La vanité. C'est par ce nom que l'homme est mauvais. Par ce nom que l'homme pille peu scrupuleusement la planète. Par ce nom que l'homme est prêt à tuer son voisin si il peut y gagner une miette de terre. Par ce nom que certains hommes sont honteusement riche. Par ce nom que l'homme a asservi l'homme, qu'il a massacré l'homme, qu'il a violé l'homme.&lt;br /&gt;C'est par ce nom que les bonnes actions ne durent pas longtemps et finissent par se transformer en corruption. C'est ce nom que je maudis tous les matins...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-8534583527536155963?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/8534583527536155963/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=8534583527536155963' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8534583527536155963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8534583527536155963'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/02/digression-sur-lincohrence-entre-les.html' title='Digression sur l&apos;incohérence entre les discours et les actions'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-6303527893391770999</id><published>2007-02-01T13:53:00.000+01:00</published><updated>2007-02-01T12:53:48.661+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>PEAR::Mail_Queue2</title><content type='html'>C'est &lt;a href="http://www.alberton.info/pear_updates_feb2007.html"&gt;annoncé officiellement&lt;/a&gt; par le mainteneur actuel du projet, je prête mes 10 doigts pour le développement du paquet PEAR::Mail_Queue2, qui est une réécriture de &lt;a href="http://pear.php.net/package/Mail_Queue"&gt;PEAR::Mail_Queue&lt;/a&gt;. En effet ce dernier souffre, comme on peut le lire sur l'interface reportant les bugs, de problèmes internes assez ennuyeux et qui ne peuvent pas être corrigés sans casser la compatibilité arrière (backward compatibility, ou BC pour les intimes).&lt;br /&gt;&lt;br /&gt;Comme le paquet PEAR::Mail_Queue est noté comme stable, la BC doit être gardée, d'où le paquet Mail_Queue2.&lt;br /&gt;&lt;br /&gt;Au menu :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Destinataires multiples,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Processing concurrent,&lt;/li&gt;&lt;li&gt;Management des erreurs,&lt;/li&gt;&lt;li&gt;Meilleure gestion du buffer de queue,&lt;/li&gt;&lt;li&gt;Multithreading (!, mais uniquement pour Unix)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;SMTP persistante,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;... (et tout ce qui me passera par la tête et sur la mailinglist) ...&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-6303527893391770999?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/6303527893391770999/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=6303527893391770999' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6303527893391770999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6303527893391770999'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/02/pearmailqueue2.html' title='PEAR::Mail_Queue2'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-7991647365173439642</id><published>2007-01-25T16:09:00.000+01:00</published><updated>2007-01-25T15:21:05.738+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smtp'/><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>Tarpitting, ou comment faire perdre de l'argent aux spammers</title><content type='html'>Le tarpitting (désolé maman pour l'utilisation d'un mot d'anglais de plus dans mes billets) est un concept émergeant dans le domaine de la protection des mails.&lt;br /&gt;&lt;br /&gt;Comme on s'aperçoit qu'on est mal embranché pour réduire la quantité de spam (voir &lt;a href="http://benoitperroud.blogspot.com/2007/01/we-are-losing-this-war-badly.html"&gt;We are loosing this war badly&lt;/a&gt;), des solutions en désespoir de cause se mettent petit à petit en place : autant essayer d'ennuyer le plus possible les spammers, en ajoutant un délai lors de la réception d'emails. La constatation est simple : si pour délivrer un mail, on ajoute un temps d'attente d'une seconde, l'utilisateur normal ne sera pas pénaliser car il n'est pas à une seconde près, mais le spammer qui envoie 1'000'000 de spam se verra pénaliser d'un million de seconde d'attente, soit plus de 11 jours. Bien sûr il &lt;strike&gt;peut&lt;/strike&gt;va paralléliser l'envoi de ses mails, mais cela ne va réduire que linéairement son temps de pénalité.&lt;br /&gt;&lt;br /&gt;De plus en plus de solution de la sorte voient le jour (principalement les systèmes de greylisting implémentent le tarpitting), et personnellement j'encourage fortement ce genre de solutions : si le mail courant est détecté comme du spam (pour éviter de reproduire ce couteux temps d'attente aux mailing "propres"), je temporise sa réception.&lt;br /&gt;&lt;br /&gt;Spammers, chez moi vous allez perdre votre argent, car le temps, c'est de l'argent !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-7991647365173439642?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/7991647365173439642/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=7991647365173439642' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7991647365173439642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7991647365173439642'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/02/tarpitting-ou-comment-faire-perdre-de.html' title='Tarpitting, ou comment faire perdre de l&apos;argent aux spammers'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-7909010079390178866</id><published>2007-01-19T16:00:00.000+01:00</published><updated>2007-01-19T15:08:00.190+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>De la sécurité des sessions PHP</title><content type='html'>Dans la majorité des espaces requierant une authentification sur un site web, le soin du suivi de l'utilisateur est laissé aux sessions, ces petits cookies qui viennent se placer chez le client afin de permettre à l'application web de le reconnaitre lors du passage à la page suivante.&lt;br /&gt;&lt;br /&gt;Ce modèle de sécurité a du être imaginé à cause de la nature "connexionless" du protocole HTTP, c'est-à-dire la fermeture de la connexion TCP au serveur entre 2 chargements de page consécutifs (contrairement aux modèles de connexions "continues").&lt;br /&gt;&lt;br /&gt;Malheureusement différentes techniques pour voler ces informations de sessions existent, elles se nomment  &lt;span style="font-style: italic;"&gt;credential token stealing&lt;/span&gt;, et sont souvent réalisables grâce à des failles de type XSS.&lt;br /&gt;&lt;br /&gt;Cet article va expliquer quel est le point faible des sessions, ainsi que présenter une solution pour en améliorer la sécurité. Un exemple d'implémentation sera une fois de plus donné en PHP.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Problèmes des sessions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Le problème lié aux sessions est que l'identité de l'utilisateur, une fois identifiée, repose entièrement sur ce cookie. Si une personne malveillante parvient à obtenir la valeur du cookie, elle pourra alors se faire passer pour la personne légitime aux yeux de l'application.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Meilleure emprunte (fingerprint)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Une première amélioration est d'associer la valeur du cookie à d'autres éléments qu'une personne malveillante ne peut pas modifier : l'ip de connexion, la signature du navigateur, etc...&lt;br /&gt;Tous ces éléments combinés ensemble donnent ce qu'on appelle l'emprunte de la session, et tous ces éléments sont nécessaires pour pouvoir usurper une identité. La principale difficulté est l'adresse ip de connexion, mais si la personne malveillante est sur le même sous-réseau que la personne légitime, l'adresse ip n'est plus un problème. Autre désavantage d'un fingerprinting étendu, si la personne légitime est sur une connexion à adresse ip dynamique, elle devra se réauthentifier à chaque changement d'adresse ip.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;ID de session temporaire&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Une autre amélioration est la regénération dynamique de la valeur du cookie. A chaque nouvelle connexion, on test si l'utilisateur est légitime, et on génère une nouvelle valeur qu'on lui envoie.&lt;br /&gt;Si une personne malveillante arrive à voler un cookie, sa valeur ne sera que temporaire et dès le prochain chargement de page, la valeur volée devient obsolète.&lt;br /&gt;Mais cela est aussi vrai à l'inverse, si la personne malveillante arrive à usurper l'identité avant que la personne légitime ne redemande une page, c'est la personne légitime qui sera déconnectée du site.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Implémentation en PHP&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Une combinaison des 2 méthodes améliorera la sécurité des sessions, sans pour autant la rendre infaillible.&lt;br /&gt;&lt;br /&gt;Voici une petite implémentation en PHP :&lt;br /&gt;&lt;pre&gt;&amp;lt;?php&lt;br /&gt;/*&lt;br /&gt;* Inspirated from SecureSession class&lt;br /&gt;* initially written by Vagharshak Tozalakyan &amp;lt;vagh@armdex.com&amp;gt;&lt;br /&gt;*/&lt;br /&gt;class SecureSession {&lt;br /&gt;&lt;br /&gt;  private $_check_browser;&lt;br /&gt;  private $_check_ip_blocks = 0;&lt;br /&gt;  private $_padding = '*ftt56+g zwc%&amp;gh7/3-lf%254*6c_qm';&lt;br /&gt;  private $_regenerate_id = true;&lt;br /&gt;  private $_session_var_name = __CLASS__;&lt;br /&gt;&lt;br /&gt;  public function _construct($check_browser = true, &lt;br /&gt;    $check_ip_block = 0, $regenerate_id = true)&lt;br /&gt;  {&lt;br /&gt;    $this-&gt;_check_browser = $check_browser;&lt;br /&gt;    $this-&gt;_check_ip_block = $check_ip_block;&lt;br /&gt;    $this-&gt;_regenerate_id = $regenerate_id;&lt;br /&gt;    &lt;br /&gt;    $_SESSION[$this-&gt;_session_var_name] = $this-&gt;_fingerprint();&lt;br /&gt;    $this-&gt;_regenerateId();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public function isValid()&lt;br /&gt;  {&lt;br /&gt;    $this-&gt;_regenerateId();&lt;br /&gt;    return (isset($_SESSION[$this-&gt;_session_var_name])&lt;br /&gt;      &amp;&amp;amp; $_SESSION[$this-&gt;_session_var_name] == $this-&gt;_fingerprint());&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private function _fingerprint()&lt;br /&gt;  {&lt;br /&gt;    $fingerprint = "";&lt;br /&gt;    if ($this-&gt;_check_browser) {&lt;br /&gt;      $fingerprint .= $_SERVER['HTTP_USER_AGENT'];&lt;br /&gt;    }&lt;br /&gt;    if ($this-&gt;_check_ip_blocks) {&lt;br /&gt;      $num_blocks = min(abs(intval($this-&gt;check_ip_blocks)), 4);&lt;br /&gt;      $blocks = explode('.', $_SERVER['REMOTE_ADDR']);&lt;br /&gt;      for ($i=0; $i&lt;$num_blocks; $i++) {&lt;br /&gt;        $fingerprint .= $blocks[$i] . '.';&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    return sha1($fingerprint . $this-&gt;_padding);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  private function _regenerateId()&lt;br /&gt;  {&lt;br /&gt;    if ($this-&gt;_regenerate_id &amp;&amp;amp; function_exists('session_regenerate_id')) {&lt;br /&gt;      session_regenerate_id(true);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-7909010079390178866?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/7909010079390178866/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=7909010079390178866' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7909010079390178866'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7909010079390178866'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/de-la-scurit-des-sessions-php.html' title='De la sécurité des sessions PHP'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2293574445155193466</id><published>2007-01-18T16:12:00.000+01:00</published><updated>2007-06-17T22:42:18.354+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>A quoi juge-t-on qu'on est trop "geek" ?</title><content type='html'>Voilà que je me surprends à ajouter subtilement des &lt;span style="font-weight: bold;"&gt;;&lt;/span&gt; à la fin des lignes d'une lettre de demande de congé pour l'armée...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Cette fois mes craintes se justifient : je suis vraiment un geek.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2293574445155193466?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2293574445155193466/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2293574445155193466' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2293574445155193466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2293574445155193466'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/quoi-juge-t-on-quon-est-trop-geek.html' title='A quoi juge-t-on qu&apos;on est trop &quot;geek&quot; ?'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-3071062663471369004</id><published>2007-01-17T12:47:00.000+01:00</published><updated>2007-01-19T07:59:27.975+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smtp'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>Une authentification sur les serveurs smtp des providers</title><content type='html'>Non content de &lt;a href="http://benoitperroud.blogspot.com/2007/01/we-are-losing-this-war-badly.html"&gt;perdre la guerre du spam&lt;/a&gt;, les providers contre-attaques.&lt;br /&gt;&lt;br /&gt;Relayé par &lt;a href="http://www.rags.ch/"&gt;Rags&lt;/a&gt;, voici le mail explicatif de Green :&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Chers clients de green.ch&lt;br /&gt;&lt;br /&gt;Dans le cadre d'un projet commun, les 4 grands fournisseurs de service internet en&lt;br /&gt;Suisse (Bluewin, Cablecom, green.ch et Sunrise) mettent en place des mesures pour&lt;br /&gt;combattre l'affluence massive des spams. La 1.ère étape est l'imposition de&lt;br /&gt;l'authentification du serveur SMTP (Simple Mail Transfert Protocole). Cela signifie&lt;br /&gt;que votre programme eMail, pour la récéption et l'envoi des emails, doit toujours&lt;br /&gt;s'authentifier au niveau du serveur mail avec un nom d'utilisateur et mot de passe.&lt;br /&gt;&lt;br /&gt;Il est possible que cela soit déjà le cas à votre niveau. Pour être sûr, nous vous&lt;br /&gt;invitons à procéder à une vérification.&lt;br /&gt;&lt;br /&gt;Le guide pour le paramétrage exacte ainsi que la configuration de votre compte eMail&lt;br /&gt;se trouve ici: http://dtg.green.ch  nous vous invitons à suivre la démarche pas à&lt;br /&gt;pas.&lt;br /&gt;&lt;br /&gt;Si vous utilisez exclusivement le Webmail pour vos eMails, vous ne devez rien&lt;br /&gt;entreprendre.&lt;br /&gt;&lt;br /&gt;Il est préférable d'effectuer le contrôle tout de suite afin de vous assurer que vos&lt;br /&gt;eMails seront aussi envoyés à l'avenir.&lt;br /&gt;&lt;br /&gt;Nous vous remercions de votre coopération.&lt;br /&gt;&lt;br /&gt;Avec nos meilleures salutations&lt;br /&gt;&lt;br /&gt;Votre équipe de support de green.ch&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Les clients des providers vont donc immédiatement devoir modifier les paramètres de leur compte mail sortant afin d'y ajouter une authentification.&lt;br /&gt;&lt;br /&gt;Cette authentification a deux effets :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;premièrement elle est &lt;span style="font-weight: bold;"&gt;ABSOLUMENT INUTILE&lt;/span&gt; contre l'envoi de spam, puisque les malwares qui envoient du spam passent très majoritairement par des open-proxies, ou se connectent directement sur le smtp du MX du domaine.&lt;/li&gt;&lt;li&gt;deuxièmement elle force à avoir une adresse email @&amp;lt;super_provider_de_luxe&amp;gt, ce qui rend les clients dépendant d'eux, car il est pénible de changer une adresse email déjà diffusée à tous ses amis/contacts. Elle empêche de ce fait le confort d'utilisation que nous fourni des adresses email comme Gmail (à noter que le webmail n'est pas touché par cette restriction).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;A mon humble avis, cette solution a dû être trouvée par les économistes du &lt;span style="font-style: italic;"&gt;top management&lt;/span&gt; et ne sert qu'à se donner un semblant de paraitre d'essayer de combattre le spam, tout en fidélisant de force leur clients.&lt;br /&gt;&lt;br /&gt;De ce point de vue, chapeau, il n'aurait jamais été si facile de faire passer la pilule sans cet argument de combattre le spam. D'un point de vu efficacité réelle, autant dire que c'est même pas un pet de constipé dans l'eau, c'est de la poudre aux yeux sans poudre. J'espère simplement que vous, chers providers, avez pensé à renforcer vos équipes de &lt;blockquote&gt;hotline&lt;/blockquote&gt;, et que vous les avez former pour répondre à la question : "Je reçois toujours autant de spam, que faire ?".&lt;br /&gt;&lt;br /&gt;Je serais tellement content de pouvoir expliquer mon &lt;strike&gt;poing&lt;/strike&gt; point de vue à un décideur d'une de ces entreprises...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-3071062663471369004?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/3071062663471369004/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=3071062663471369004' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3071062663471369004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3071062663471369004'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/une-authentification-sur-les-serveurs.html' title='Une authentification sur les serveurs smtp des providers'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-3043376676265010401</id><published>2007-01-16T16:07:00.000+01:00</published><updated>2007-01-16T15:10:20.301+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Les 7 règles fondamentales en sécurité</title><content type='html'>Très souvent oubliées ou minimisées, voici les 7 règles fondamentales en sécurité :&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Least privilege&lt;/span&gt; : on ne donne que le privilege minimum&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Defense in depth&lt;/span&gt; : on protége à tous les niveaux&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Choke point&lt;/span&gt; : on emprunte qu’un seul chemin pour aller au but&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Weakest link&lt;/span&gt; : la sécurité globale est égale à la sécurité du maillon le plus faible&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Default deny&lt;/span&gt; : plutôt que d’énumérer les cas pas permis, au risque d’en oublier, on énumère les cas permis.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;User participation&lt;/span&gt; : on éduque les utilisateurs par rapport à la sécurité&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Simplicity&lt;/span&gt; : on applique le principe de simplicité&lt;/li&gt;&lt;/ol&gt;A appliquer sans modération !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-3043376676265010401?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/3043376676265010401/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=3043376676265010401' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3043376676265010401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3043376676265010401'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/les-7-rgles-fondamentales-en-scurit.html' title='Les 7 règles fondamentales en sécurité'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-4163016752144479013</id><published>2007-01-15T12:30:00.000+01:00</published><updated>2007-01-15T11:30:11.453+01:00</updated><title type='text'>Statistiques fournies par FeedBurner</title><content type='html'>Je suis relativement content de mon blog sur Blogger.com, les principaux problèmes que j'y vois sont :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Pas la possibilité de faire des trackbacks&lt;/li&gt;&lt;li&gt;Pas de statistiques de fréquentation.&lt;/li&gt;&lt;/ul&gt;Le premier problème n'a pas l'air prêt de se régler, le deuxième peut en revanche être contourner en passant par &lt;a href="http://www.feedburner.com/"&gt;Feedburner&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Chose faite, il serait bien d'actualiser vos bookmarks de feed et s'abonner à http://feeds.feedburner.com/BenoitPerroud plutôt que l'alternative de Blogger.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-4163016752144479013?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/4163016752144479013/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=4163016752144479013' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4163016752144479013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4163016752144479013'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/statistiques-fournies-par-feedburner.html' title='Statistiques fournies par FeedBurner'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-6599395184325265093</id><published>2007-01-14T23:34:00.000+01:00</published><updated>2007-01-16T15:18:03.049+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Form flooding</title><content type='html'>Les formulaires sont un des points vulnérables d'une application web, car c'est notamment à travers eux que les "clients" peuvent injecter des données dans l'application.&lt;br /&gt;&lt;br /&gt;De plus, même si le formulaire est suffisamment protégé contre l'injection de données, qu'elle soit XSS, SQL, &lt;span style="font-style: italic;"&gt;string format&lt;/span&gt; ou autre, le formulaire reste vulnérable à un &lt;a href="http://fr.wikipedia.org/wiki/Flood"&gt;flood&lt;/a&gt; :&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Comment réagit votre formulaire si un client bien authentifié décide de poster 1'000'000 de fois le formulaire ? &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Ce genre d'attaque peut avoir des effets très néfastes...&lt;br /&gt;&lt;br /&gt;Il y a plusieurs méthodes pour s'en prémunir, et je vais en présenter une qui, contrairement au &lt;span style="font-style: italic;"&gt;&lt;a href="http://fr.wikipedia.org/wiki/Captcha"&gt;captcha&lt;/a&gt;&lt;/span&gt;, ne requiert pas d'intervention de la part de l'utilisateur (on ne peut pas faire de captcha dans un &lt;a href="http://fr.wikipedia.org/wiki/Webservice"&gt;webservice&lt;/a&gt;...), mais protège tout de même notre formulaire.&lt;br /&gt;&lt;br /&gt;On va donc attribuer à chaque formulaire un identifiant unique, qui est entré dans une table (ou en var de session) conjointement avec un timestamp. L'identifiant nous permettra d'éviter (au pire de remarquer) la soumission multiple du même formulaire, et grâce au timestamp, nous pourrons mesurer le temps entre le chargement de la page contenant le formulaire et son renvoi au serveur, temps qui ne devrait pas être inférieur à une voir plusieurs secondes pour un utilisateur humain, selon la taille du formulaire.&lt;br /&gt;&lt;br /&gt;En recevant le formulaire, le serveur peut donc contrôler si :&lt;br /&gt;&lt;br /&gt;1. Le formulaire est valide, i.e. l'identifiant du formulaire est valide&lt;br /&gt;2. Le formulaire n'a pas été envoyé plusieurs fois.&lt;br /&gt;3. Le délai de soumission du formulaire n'est pas trop élevé pour une session donnée.&lt;br /&gt;&lt;br /&gt;L'implémentation de cette solution est elle aussi multiple, mais j'en donne un exemple ci-dessous :&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;__toString(); ?&gt; ...&lt;br /&gt;*&lt;br /&gt;* if (isset($_POST)) {&lt;br /&gt;*   $canary = Form_Protector::factory($_POST);&lt;br /&gt;*   if (!$canary-&gt;is_valid()) {&lt;br /&gt;*     if ($canary-&gt;exists()) {&lt;br /&gt;*       // le canary n'existait pas dans la db, afficher un message d'erreur et recharger la page&lt;br /&gt;*     } else {&lt;br /&gt;*       // le formulaire a été posté trop rapidement, on peut donc compter le nombre de soumissions durant les 5 dernières minutes, et prendre une des actions suivante&lt;br /&gt;*       // --&gt; soit on blacklist l'ip un moment,&lt;br /&gt;*       // --&gt; soit on sleep(30) pour temporiser (tarpitting)&lt;br /&gt;*     }&lt;br /&gt;*   } else {&lt;br /&gt;*     // le canary est valide, tout est bien dans le meilleur des mondes.&lt;br /&gt;*   }&lt;br /&gt;* }&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;define("_TIME_TO_SUBMIT_FORM", 2); // temps que l'utilisateur fait pour submiter un formulaire&lt;br /&gt;class Form_Protector {&lt;br /&gt;&lt;br /&gt;protected $_canary;&lt;br /&gt;protected $_ip;&lt;br /&gt;protected $_date_request;&lt;br /&gt;protected $_date_request;&lt;br /&gt;protected $_exists = false;&lt;br /&gt;&lt;br /&gt;public static $input_name = 'form_protector_canary';&lt;br /&gt;&lt;br /&gt;protected function __construct($canary = 0, $ip = "") {&lt;br /&gt;  $this-&gt;_ip = $_SERVER['REMOTE_ADDR'];&lt;br /&gt;  if ($canary === 0) {&lt;br /&gt;    $this-&gt;_canary = rand();&lt;br /&gt;    $this-&gt;_insert();&lt;br /&gt;  } else {&lt;br /&gt;    $this-&gt;_canary = $canary;&lt;br /&gt;    if ($ip !== "") $this-&gt;_ip = $ip;&lt;br /&gt;    $this-&gt;_load();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected function _load() {&lt;br /&gt;  $query = sprintf("SELECT * FROM form_protector&lt;br /&gt;    WHERE canary = %d AND ip = '%s'" . int_val($this-&gt;_canary),&lt;br /&gt;    mysql_real_secape($this-&gt;_ip));&lt;br /&gt;  // query,&lt;br /&gt;  // load $this-&gt;_date_request, $this-&gt;_date_request = time();&lt;br /&gt;  // si pas un champ est retourné, on passe $this-&gt;_exists à true; et on UPDATE ... SET date_response = $this-&gt;_date_request&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;protected function _insert() {&lt;br /&gt;$this-&gt;_date_request = time();&lt;br /&gt;$query = sprintf("INSERT INTO form_protector (canary, ip, date_request) VALUES (%d, %s, %d)", int_val($this-&gt;_canary), mysql_real_secape($this-&gt;_ip), $this-&gt;_date_request);&lt;br /&gt;// query&lt;br /&gt;// si pas d'erreur : $this-&gt;_exists = true;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public function is_valid() {&lt;br /&gt;if ($this-&gt;_date_request + _TIME_TO_SUBMIT_FORM &lt;&gt;_exists;&lt;br /&gt;}&lt;br /&gt;public function __toString() {&lt;br /&gt;return '&amp;lt;input value="' . $this-&gt;_canary . '" name="form_protector_canary" type="hidden"&amp;gt;';&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static factory($params = NULL) {&lt;br /&gt;if (is_array($params) &amp;&amp;amp; isset($params[self::$name])) {&lt;br /&gt; $canary = $params[self::$name];&lt;br /&gt;} else {&lt;br /&gt; if ($params === NULL) {&lt;br /&gt;  $canary = 0;&lt;br /&gt; } else {&lt;br /&gt;  $canary = $params;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;return new Form_protector($canary);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;?&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-6599395184325265093?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/6599395184325265093/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=6599395184325265093' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6599395184325265093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6599395184325265093'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/02/form-flooding.html' title='Form flooding'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-6697776448870699505</id><published>2007-01-14T18:20:00.000+01:00</published><updated>2007-01-14T17:27:59.475+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='smtp'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>We are losing this war badly</title><content type='html'>Ou "Quand les RFCs sont trop difficiles à comprendre..."&lt;br /&gt;&lt;br /&gt;Quand un serveur SMTP se connecte à un autre pour envoyer un mail, il doit s'annoncer. Cela fait parti du protocole SMTP définit dans la &lt;a href="http://www.ietf.org/rfc/rfc2821.txt"&gt;RFC 2821&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;- Connexion TCP à &amp;lt;server_destinataire&amp;gt; (telnet &amp;lt;server_destinataire&amp;gt; 25 pour simuler le comportent)&lt;br /&gt;- HELO &amp;lt;server_name&amp;gt; (ou EHLO dans le cas de ESMTP)&lt;br /&gt;&lt;br /&gt;Ce HELO &amp;lt;server_name&amp;gt; est une petite politesse introduite dans le protocole, mais qui permet, en plus de choisir la version de SMTP lors de l'échange, d'ajouter des tests pour détecter le spam.&lt;br /&gt;&lt;br /&gt;En effet, à l'heure actuelle la plupart des moteurs SMTP utilisés pour envoyer du spam ne s'annoncent pas correctement. Le &amp;lt;server_name&amp;gt; est très souvent remplacé par une chaine de caractères aléatoires.&lt;br /&gt;Si on part du principe qu'un serveur mail légitime a une adresse ip fixe, la correspondance entre l'ip inverse de &amp;lt;server_name&amp;gt; et de l'ip de la connexion du serveur serait un très bon test pour contrer le spam. Le problème devient un cauchemar quand même des providers ne configurent par correctement leurs serveurs SMTP : &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Received: from smtp-auth-be-03.sunrise.ch (mail-proxy-be-01.sunrise.ch [194.158.229.48])&lt;br /&gt;        (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))&lt;br /&gt;        by dns3.omne-serveurs.net (Postfix) with ESMTP id 342991EEE10&lt;br /&gt;        for &lt;info@*******&gt;; Sun, 31 Dec 2006 02:16:16 +0100 (CET)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Dans cet exemple, il s'agit d'un serveur Sunrise qui s'annonce &lt;span style="font-style:italic;"&gt;smtp-auth-be-03.sunrise.ch&lt;/span&gt;, et dont l'ip est &lt;span style="font-style:italic;"&gt;194.158.229.48&lt;/span&gt;. C'est presque juste, le seul détail est que le reverse de &lt;span style="font-style:italic;"&gt;194.158.229.48&lt;/span&gt; est &lt;span style="font-style:italic;"&gt;mail-proxy-be-01.sunrise.ch&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Received: from swip.net (mailfe05.tele2.ch [212.247.154.136])&lt;br /&gt;        by dns3.omne-serveurs.net (Postfix) with ESMTP id 0173F763C3C&lt;br /&gt;        for &lt;info@*******&gt;; Wed, 10 Jan 2007 07:54:31 +0100 (CET)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Dans ce deuxième exemple, la configuration est pire : le serveur qui se connecte avec l'ip &lt;span style="font-style:italic;"&gt;212.247.154.136&lt;/span&gt;, s'annonce comme étant &lt;span style="font-style:italic;"&gt;swip.net&lt;/span&gt;, alors que le reverse de &lt;span style="font-style:italic;"&gt;swip.net&lt;/span&gt; est &lt;span style="font-style:italic;"&gt;212.247.156.1&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;En résumé, parce que les personnes qui administrent des serveurs mails ne sont pas un peu plus scrupuleux, comme il est dit dans &lt;a href="http://www.nytimes.com/2007/01/07/technology/07net.html"&gt;cet article&lt;/a&gt;  &lt;br /&gt;&lt;blockquote&gt;We are losing this war badly&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-6697776448870699505?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/6697776448870699505/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=6697776448870699505' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6697776448870699505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6697776448870699505'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/we-are-losing-this-war-badly.html' title='We are losing this war badly'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5025212821373031453</id><published>2007-01-11T07:32:00.000+01:00</published><updated>2007-01-12T09:22:10.043+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Nabuchodonosor, Roi de Babylone, écrivez-moi cela en 4 lettres.</title><content type='html'>&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Nabuchodonosor, Roi de Babylone, écrivez-moi cela en 4 lettres.&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Cette expression est ma dernière signature en date, et comme d'habitude personne ne comprend son sens profond, alors je me vois contrains de l'expliquer.&lt;br /&gt;&lt;br /&gt;Le but de cette phrase est de faire paraitre quelque chose compliqué alors qu'elle ne l'est en réalité pas (tout le monde peut écrire cela en 4 lettres : c e l a. Pas besoin d'être roi de Babylone pour le faire). &lt;br /&gt;&lt;br /&gt;Il en est de même dans beaucoup de domaine de l'ingénierie, où des gens ont la fâcheuse tendance à compliquer des concepts simples (pour justifier leur travail, pour faire plus vendeur, ou pour n'importe quelle autre raison qui m'échappe). Il y a bien évidement des cas où cette complication est nécessaire (pour un obfuscateur de code source par exemple), mais retenons et appliquons la devise d'Albert Einstein : &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight:bold;font-style:italic;"&gt;Faites les choses aussi simple que possible, mais pas plus simple.&lt;/span&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5025212821373031453?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5025212821373031453/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5025212821373031453' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5025212821373031453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5025212821373031453'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/nabuchodonosor-roi-de-babylone-crivez.html' title='Nabuchodonosor, Roi de Babylone, écrivez-moi cela en 4 lettres.'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-7697801801558593591</id><published>2007-01-09T00:10:00.000+01:00</published><updated>2007-01-15T21:09:36.825+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='optimisation'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Optimisation du nombre de requêtes SQL dans les collections d'objets et relation n-m</title><content type='html'>L'orientation objet de PHP n'est plus contestable, mais les problèmes d'optimisation persistent.&lt;br /&gt;&lt;br /&gt;Par exemple le malheureusement célèbre &lt;span style="font-style: italic;"&gt;n+1 pattern&lt;/span&gt;, qui fait que pour afficher une liste de &lt;span style="font-style: italic;"&gt;n&lt;/span&gt; objets, le &lt;span style="font-style: italic;"&gt;+ 1&lt;/span&gt; étant la requête qui sélectionne tous les ids des objets à instancier, &lt;span style="font-style: italic;"&gt;n + 1&lt;/span&gt; requêtes SQL seront effectuées.&lt;br /&gt;&lt;br /&gt;De même dans des relations &lt;span style="font-style: italic;"&gt;n-m&lt;/span&gt;, la majorité des implémentations sélectionnent les &lt;span style="font-style: italic;"&gt;n&lt;/span&gt; objets (en n + 1 requêtes donc), puis pour chacun on sélectionne les &lt;span style="font-style: italic;"&gt;m&lt;/span&gt; objets de la relation. On obtient donc &lt;span style="font-style: italic;"&gt;n * m + 1&lt;/span&gt; requêtes.&lt;br /&gt;&lt;br /&gt;Le but de cet article est de présenter deux techniques qui, combinées, réduisent les &lt;span style="font-style: italic;"&gt;n * m + 1&lt;/span&gt; requêtes en &lt;span style="font-style: italic;"&gt;n + m + 1&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Les deux techniques que je vais illustrer ici se nomment &lt;span style="font-style: italic;"&gt;object caching&lt;/span&gt; et &lt;span style="font-style: italic;"&gt;grouped fetching&lt;/span&gt;. Elles se combinent très bien, ce qui permet d'optimiser drastiquement les performances d'un script PHP, du points de vue I/O (moins de requêtes), vitesse d'exécution et même mémoire utilisée (les objets ne sont pas dupliqués).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Object caching : &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Le principe de l'&lt;span style="font-style: italic;"&gt;object caching&lt;/span&gt; est de rendre le constructeur de l'objet privé (au pire protégé) et de l'instancier au moyen d'une &lt;span style="font-style: italic;"&gt;factory&lt;/span&gt;. Puis on ajoute à la classe un tableau statique dans lequel les références des objets instanciés seront placés. La factory va donc regarder dans le tableau de références si l'objet existe, et si ça n'est pas le cas elle va le créer, l'ajouter au tableau et le retourner.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class A {&lt;br /&gt; protected static $objects_cache = array();&lt;br /&gt;&lt;br /&gt; public static function factory($id, $class = __CLASS__)&lt;br /&gt; {&lt;br /&gt;   if (array_key_exists($id, $class::$objects_cache)) {&lt;br /&gt;     return $class::$objects_cache[$id];&lt;br /&gt;   } else {&lt;br /&gt;     $o = new $class($id);&lt;br /&gt;     $class::$objects_cache[$id] = $o;&lt;br /&gt;     return $o;&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Cette solution pourrait encore être améliorée si les objets pouvaient être partagés entre toutes les instances de PHP. Ce n'est pas le cas à cause de l'architecture &lt;span style="font-style: italic;"&gt;share nothing&lt;/span&gt; de PHP, et c'est un des points forts des serveurs d'applications.&lt;br /&gt;Un autre désavantage de ce concept, si on a un script qui tourne suffisamment longtemps pour que le &lt;span style="font-style: italic;"&gt;grabage collector&lt;/span&gt; se lance, est que tous les objets créés sont toujours référencés, même ceux qui pourraient être des candidats potentiels à la finalisation. Ce problème est résolu dans d'autres langages, en Java par exemple grâce aux références faibles (&lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ref/WeakReference.html"&gt;WeakReference&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Grouped fetching&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Le principe du &lt;span style="font-style: italic;"&gt;grouped fetching&lt;/span&gt;, dérivé d'une solution proposée par notre ami &lt;a href="http://www.colder.ch/"&gt;Colder&lt;/a&gt;, est de charger les données des objets de manière asynchrone et en bloque. Quand un objet est instancié, il est marqué comme non chargé, et sa référence est placée dans un tableau global de la classe. Puis lors d'un accès à un champ non chargé, la classe va sélectionner dans la base de données tous les objets instanciés mais pas encore chargés. Plus on retarde les accès aux attributs d'un objet, plus on va paralléliser les requêtes SQL.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class A {&lt;br /&gt; private static $_to_load = array();&lt;br /&gt; private $_is_loaded = false;&lt;br /&gt; public function __construct($id)&lt;br /&gt; {&lt;br /&gt;   $this-&gt;id = $id;&lt;br /&gt;   self::$_to_load[$id] = $this;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public function __get($attribut)&lt;br /&gt; {&lt;br /&gt;   if (!$this-&gt;_is_loaded) {&lt;br /&gt;     self::_groupedLoad();&lt;br /&gt;   }&lt;br /&gt;   return $this[$attribut];&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private function _setLoaded()&lt;br /&gt; {&lt;br /&gt;   $this-&gt;is_loaded = true;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private static function _groupedLoad()&lt;br /&gt; {&lt;br /&gt;   $ids = implode(', ', self::$_to_load);&lt;br /&gt;   $query = 'SELECT * FROM ' . self::$_table . ' WHERE id IN ( ' . $ids . ' ) ';&lt;br /&gt;   $res = db_query($query);&lt;br /&gt;   while ($row = $res-&gt;getNext()) {&lt;br /&gt;     self::_to_load[$row['id']]-&gt;_initByArray($row);&lt;br /&gt;     self::_to_load[$row['id']]-&gt;_setLoaded;&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;L'overhead de ce concept est très faible (un tableau de références supplémentaire), et le nombre d'accès à la base de données sont grandement réduit. Mais le problème de la finalisation des objets se repose aussi.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-7697801801558593591?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/7697801801558593591/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=7697801801558593591' title='3 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7697801801558593591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7697801801558593591'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/optimisation-du-nombre-de-requtes-sql.html' title='Optimisation du nombre de requêtes SQL dans les collections d&apos;objets et relation n-m'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-4695674986668683011</id><published>2007-01-08T12:19:00.000+01:00</published><updated>2007-01-08T12:21:52.510+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Lettre au père Noël</title><content type='html'>Trouvé sur linuxfr, tellement plein de vrai que je suis obligé de broadcaster : &lt;br /&gt;&lt;br /&gt;&lt;a href="http://linuxfr.org/2007/01/03/21814.html"&gt;Lettre au père Noël&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-4695674986668683011?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/4695674986668683011/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=4695674986668683011' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4695674986668683011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4695674986668683011'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/lettre-au-pre-nol.html' title='Lettre au père Noël'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2525528436429765661</id><published>2007-01-07T22:24:00.000+01:00</published><updated>2007-01-09T09:27:44.025+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Samourai</title><content type='html'>Et voici un autre jeu à boire intéressant, appris sur le tas dans de sombres circonstances, et dont l'issue fut fatale pour plus d'un d'entre nous. Il s'appelle &lt;span style="font-style: italic;"&gt;Samourai &lt;/span&gt;, et le principe est très simple : des personnes autour d'une table devant accomplir chacun leur tour une ou plusieurs actions.&lt;br /&gt;&lt;br /&gt;Les actions sont simples, elles consistent à désigner la personne suivante à réaliser l'action, à &lt;strike&gt;boire un verre de vodka cul-sec&lt;/strike&gt; réaliser un gage ou faire un action collective.&lt;br /&gt;&lt;br /&gt;Le nom des actions étant normalement en japonais, je me permets d'y faire ici une transcription phonétique.&lt;br /&gt;&lt;br /&gt;L'action la plus simple consiste à désigner son voisin direct par un coup de coude latéral, le poing du bras donnant le coup de coude dans la paume l'autre main, en criant "Hi-ha". La seule contrainte sur cette action est qu'elle doit se faire dans la même direction que le coup de coude reçu (donc on reçoit un coup de coude du coté gauche et on renvoie un coup de coude sur notre droite, respectivement le coté gauche de notre voisin).&lt;br /&gt;&lt;br /&gt;La deuxième action permet de désigner n'importe quelle personne autour de la table. Cela se fait en tendant sa main bien droite en direction de cette personne et en criant "Katana".&lt;br /&gt;&lt;br /&gt;L'action "Oups" permet de faire sauter le tour du voisin dans lequel l'action de se déplace. Elle se réalise en décrivant un cercle de la taille d'un ballon de foot avec ses 2 mains.&lt;br /&gt;&lt;br /&gt;L'action pour bloquer le coup de coude et faire repartir le mouvement dans le sens contraire s'appelle "Wasaï". Elle se réalise en plaçant devant soi son avant-bras à la verticale et son poing contre son coude opposé, le tout en criant "Wasaï". Si on reçoit un "Hi-ha" par la gauche, on doit lever son avant-bras droite, de manière à avoir le coude gauche à l'horizontal pour répondre à son voisin de gauche.&lt;br /&gt;&lt;br /&gt;Les 2 prochaines actions peuvent être exécuter en plus de l'action de base, et tous les autres joueurs doivent y répondre :&lt;br /&gt;Si le jour crie "Aligato", les autres joueurs joignent leurs mains dans un signe de prière, s'inclinent vers le joueur qui a prononcé ce mot et réponde "Aligato san".&lt;br /&gt;De même si le joueur crie "Samourai", les autres joueurs imitent l'action de resserrer un noeud autour de la taille en criant "Hou".&lt;br /&gt;&lt;br /&gt;Puis vient le moment du gage. Le joueur qui exécute incorrectement un action cité doit donc &lt;strike&gt;boire un verre&lt;/strike&gt; exécuter un gage. Avant son gage, il doit prononcer "Arakiri", que tout le monde doit applaudir, puis il doit remercier Yogi à la fin du gage. Si ces 2 parties du gage sont mal exécutées, le gage entier doit être refait.&lt;br /&gt;&lt;br /&gt;Dernière action en date, similaire à "Katana", le joueur désigne un autre joueur en criant "Nikon". Le joueur visé doit alors viser un autre joueur en imitant d'avoir un appareil photo dans les mains et crie "click-clack".&lt;br /&gt;&lt;br /&gt;A noter qu'il serait judicieux d'introduire progressivement les règles, avec dans l'ordre :&lt;br /&gt;&lt;ol&gt;&lt;li&gt;"Hi-ha"&lt;/li&gt;&lt;li&gt;"Wasaï"&lt;/li&gt;&lt;li&gt;"Oups"&lt;/li&gt;&lt;li&gt;"Samourai"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"Katana"&lt;/li&gt;&lt;li&gt;"Aligato"&lt;/li&gt;&lt;li&gt;"Nikon"&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;&lt;strike&gt;Bonne guerre&lt;/strike&gt; Bon jeu !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2525528436429765661?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2525528436429765661/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2525528436429765661' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2525528436429765661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2525528436429765661'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/samourai.html' title='Samourai'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5567382182258763894</id><published>2007-01-07T19:25:00.000+01:00</published><updated>2007-01-08T16:41:53.423+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='optimisation'/><title type='text'>De l'art d'éviter les requêtes SQL inutiles</title><content type='html'>Dans le domaine de l'optimisation, une chose simple à faire est d'essayer de réduire au strict minimum le nombre de requêtes à faire à la base de données.&lt;br /&gt;&lt;br /&gt;Je souhaite simplement rendre attentif au problème posé par les procédures embarquées et autres tirggers :&lt;br /&gt;&lt;br /&gt;Dans le cas d'une mise-à-jour d'un objet mappé sur une table d'une base de données, les champs de l'objet sont remplacés (après nettoyage...) par ceux du formulaire. On pourrait donc penser qu'il est inutile de faire un SELECT juste après un UPDATE, car les données mises-à-jour sont celles fournies.&lt;br /&gt;&lt;br /&gt;Cela est vrai sans compter sur les triggers déclenchés en cas de mises-à-jour : sans un SELECT après l'UPDATE, certains champs peuvent contenir des données fausses car non traitées par le trigger. Les champs auto-timestamp de Mysql sont un exemple tout simple de trigger à ne pas oublier...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5567382182258763894?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5567382182258763894/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5567382182258763894' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5567382182258763894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5567382182258763894'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/de-lart-dviter-les-requtes-sql-inutiles.html' title='De l&apos;art d&apos;éviter les requêtes SQL inutiles'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2905699374633613088</id><published>2007-01-04T07:53:00.000+01:00</published><updated>2007-01-04T08:01:56.306+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Bonne année (2007) !</title><content type='html'>Version geek : &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;if (date('n') === 1&lt;br /&gt;    &amp;&amp; ($day = date('j')) &amp;gt;= 1 &amp;&amp; $day &amp;lt; 10) {&lt;br /&gt;    echo '&amp;lt;p&amp;gt;Bonne année ' . date('Y') . ' à tous !&amp;lt;/p&amp;gt;';&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Version "Le Chat" : &lt;br /&gt;&lt;blockquote&gt;Meilleurs voeux pour toute la vie.. Comme ça c'est fait une  &lt;br /&gt;fois pour toutes !&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2905699374633613088?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2905699374633613088/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2905699374633613088' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2905699374633613088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2905699374633613088'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2007/01/bonne-anne-2007.html' title='Bonne année (2007) !'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-997061765524165089</id><published>2006-12-30T11:06:00.000+01:00</published><updated>2006-12-30T12:18:39.913+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Surchages de méthodes statiques en PHP</title><content type='html'>Un tout petit exemple pour exposer le problème : &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;class A {&lt;br /&gt;&amp;nbsp;&amp;nbsp;public static function f() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo get_class();&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class B extends A {}&lt;br /&gt;&lt;br /&gt;A::f();&lt;br /&gt;B::f(); &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;A::f() va afficher A, par contre B::f() va aussi afficher A, alors que la réponse attendue serait B.&lt;br /&gt;&lt;br /&gt;Ce comportement est connu des développeurs OO, peut s'avérer ennuyeux dès qu'on utilise des fonctions statiques surchargées, car les appels à self::une_fonction() (une_fonction est donc une méthode statique) dans le parent résulteront toujours à un appel de la méthode du parent, et non pas celle surchargée dans le fils. La raison est que self dans la classe parente représente le parent, comme c'est aussi le cas dans d'autres langages OO.&lt;br /&gt;Illustrons les limites de ce comportement avec la mise en place d'une factory toute simple : &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;class A {&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;public static function create($params) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$class = get_class();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return new $class($params);&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;class B extends A {}&lt;br /&gt;$b = B::create($myparams);&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;$b&lt;/span&gt; contiendra toujours un objet de classe A, car &lt;span style="font-style:italic;"&gt;get_class&lt;/span&gt; retournera toujours A. &lt;br /&gt;&lt;br /&gt;L'idée pour palier à cette limitation est donc simplement d'ajouter un argument à la fonction &lt;span style="font-style:italic;"&gt;create&lt;/span&gt; de A, qui sera la classe à instancer : &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;class A {&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;public static function create($params, $class = __CLASS__) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return new $class();&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;class B extends A {&lt;br /&gt;&amp;nbsp;&amp;nbsp;public static function create($params, $class = __CLASS__) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;return parent::create($params, $class);&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;$b = B::create($myparams);&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Avec cette petite adaptation, $b sera bien un objet B.&lt;br /&gt;&lt;br /&gt;De manière plus général, si on envisage d'utiliser des fonctions statiques surchargées, PHP nous permet de gérer l'héritage en passant la classe en argument et en appelant la fonction statique au moyen de la macro &lt;span style="font-style:italic;"&gt;call_user_func&lt;/span&gt; : &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;class A {&lt;br /&gt;&amp;nbsp;&amp;nbsp;protected static une_fonction($arg) { return $arg + 1; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;public static function create($params, $class = __CLASS__) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;$res = call_user_func(array($class, 'une_fonction'), $args);&lt;br /&gt;&amp;nbsp;&amp;nbsp;...&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;class B extends A {&lt;br /&gt;&amp;nbsp;&amp;nbsp;protected static une_fonction($arg) { return $arg + 2; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;public static function create($params, $class = __CLASS__) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;return parent::create($params, $class);&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;$b = B::create($myparams);&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Grâce à cette macro &lt;span style="font-style:italic;"&gt;call_user_func&lt;/span&gt;, &lt;span style="font-style:italic;"&gt;B::create&lt;/span&gt; appellera donc bien &lt;span style="font-style:italic;"&gt;B::une_fonction&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-997061765524165089?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/997061765524165089/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=997061765524165089' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/997061765524165089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/997061765524165089'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/12/surchages-de-mthodes-statiques-en-php.html' title='Surchages de méthodes statiques en PHP'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2898069084611020666</id><published>2006-12-21T08:30:00.000+01:00</published><updated>2006-12-21T08:33:38.400+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>Spam image</title><content type='html'>Selon une analyse menée par une société spécialisée dans la sécurité informatique, le spam image a augmenté de façon impressionnante en un an, passant de 4,8 % du spam global en octobre 2005 à 25 % un an plus tard. Loin d'être en recul, le volume global du spam est passé de 31 milliards de messages par jour à &lt;span style="font-weight:bold;"&gt;61 milliards&lt;/span&gt; sur la même période. De plus la taille moyenne des messages a elle aussi augmenté, passant de 8,9 Ko à 13 Ko. Le spam consomme donc désormais &lt;span style="font-weight:bold;"&gt;819 téraoctets de bande passante par jour&lt;/span&gt; !&lt;br /&gt;&lt;br /&gt;En attendant que d'efficaces techniques de prévention du spam image soient mises au point, n'hésitons pas à désactiver l'affichage automatique des images dans notre gestionnaire de courrier, ce sera déjà une première défense. Et ayons toujours en tête que le but des spammeurs est moins de vous vendre quelque chose que de vous arnaquer purement et simplement...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2898069084611020666?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2898069084611020666/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2898069084611020666' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2898069084611020666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2898069084611020666'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/12/spam-image.html' title='Spam image'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-8439043404457486270</id><published>2006-12-19T11:42:00.000+01:00</published><updated>2006-12-19T12:10:43.305+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><category scheme='http://www.blogger.com/atom/ns#' term='opensource'/><title type='text'>Ryzom, un MMORPG désormais libre</title><content type='html'>Un fait peu habituel secoue l'univers du libre ces derniers jours : le rachat de la propriété intellectuelle (code source, monde, ...) du jeu de type MMORPG nommé &lt;a href="http://www.ryzom.fr/"&gt;Ryzom&lt;/a&gt; afin de la libérer. &lt;br /&gt;&lt;br /&gt;Cette initiative, soutenue par la &lt;a href="http://www.fsf.org/"&gt;FSF&lt;/a&gt; elle-même qui y joue un important rôle de mécène, montre à quel point l'univers du libre est réactif et motivé, mais pointe le doigt sur un fondement de notre société capitaliste :&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight:bold;"&gt;La liberté a un prix.&lt;span style="font-style:italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;On peut donc en déduire comme corolaire qu'il faut gagner de l'argent pour rester libre.&lt;br /&gt;&lt;br /&gt;Et tout le paradoxe du serpent qui se mort la queue apparait quand on prend le cas la &lt;a href="http://www.mozilla.org/foundation/"&gt;Fondation Mozilla&lt;/a&gt;, qui gagne de l'argent grâce a des partenariats avec notamment Google, faits incompris et fortement critiqués par beaucoup de monde (actualité sur par exemple &lt;a href="http://www.zdnet.fr/actualites/informatique/0,39040745,39364463,00.htm"&gt;1&lt;/a&gt; et &lt;a href="http://www.neteco.com/article_20061027185424_mozilla_mal_a_l_aise_avec_les_millions_de_dollars_generes_par_firefox.html"&gt;2&lt;/a&gt;, critiques dans la blogoshpère).&lt;br /&gt;&lt;br /&gt;Une petite illustration logique pour toutes les personnes qui n'auraient pas compris l'intérêt de la Fondation Mozilla : &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Il faut gagner de l'argent pour être libre.&lt;br /&gt;La fondation Mozilla gagne de l'argent.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Donc la fondation Mozilla est libre.&lt;/span&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-8439043404457486270?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/8439043404457486270/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=8439043404457486270' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8439043404457486270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8439043404457486270'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/12/ryzom-un-mmorpg-dsormais-libre.html' title='Ryzom, un MMORPG désormais libre'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-8837428303682967959</id><published>2006-12-18T16:34:00.000+01:00</published><updated>2006-12-18T23:09:01.034+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Reverse MD5</title><content type='html'>La fonction MD5 est une fonction dit à sens unique, c'est-à-dire que ne connaissant que la sortie, il est difficile de trouver l'entrée qui a produit cette sortie.&lt;br /&gt;&lt;br /&gt;C'est pourquoi des &lt;span style="font-style: italic;"&gt;reverse md5 databases&lt;/span&gt; sont apparues sur Internet. Leur principe est tout simple : c'est une grande base de données contenant la pair (texte, hash). Ainsi on peut la questionner du hash recherché et elle nous retourne le texte correspondant si il est connu.&lt;br /&gt;&lt;br /&gt;La base de données doit donc être remplie avant de pouvoir produire des réponses, mais une fois qu'elle contient suffisamment de données, les recherches peuvent commencer à être intéressantes. Les techniques des remplissages sont simples, elles vont du parcours de pages web ou de dictionnaires pour rechercher des mots quelconques à l'ajout manuel par des utilisateurs.&lt;br /&gt;&lt;br /&gt;J'ai rapidement fait une petite application qui questionne plusieurs des ces &lt;span style="font-style: italic;"&gt;reverse md5 databases&lt;/span&gt;, qui elle est disponible à l'addresse &lt;a href="http://md5.noisette.ch/form.php"&gt;http://md5.noisette.ch/form.php&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Elle se base sur la toute petite API suivante : http://md5.noisette.ch/?hash=&amp;lt;le_hash_en_hex&amp;gt; qui retourne du XML&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&amp;lt;md5lookup&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;hash&amp;gt;&amp;lt;!--[CDATA[2a0231531bc1a7fc29e2fa8d64352ae9]]--&amp;gt;&amp;lt;/hash&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;string&amp;gt;&amp;lt;!--[CDATA[noisette]]--&amp;gt;&amp;lt;/string&amp;gt;&lt;br /&gt;&amp;lt;/md5lookup&amp;gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;L'approche est très alléchante car une fois le hash dans la base de données, les réponses sont fournies en O(1). Les mots de passe stockés en md5 peuvent donc être retrouvés extrèmenent rapidement.&lt;br /&gt;La contre-partie de cette approche est qu'elle nécessite beaucoup de hash précalculé avant d'être utilisable, et donc produira une énorme base de données :&lt;br /&gt;Le md5 étant sur 128 bits, on pourrait avoir une table de 2^^128 entrées, pour peu qu'on ne prenne pas en compte les doublons. Donc rien que pour les hash, il nous faudrait ~5*10^^39 bytes de stockage = ~5000 téra de téra de téra bytes. Enfin juste pas possible quoi. Si on fait le raisonnement inversion on se dit que notre serveur a 200Gb d'espace disque, on peut donc stocker 12.5 milliards de hash, donc 12.5 milliards de possibilités de mots de passe = un peu plus de 2^^33 possibilités. On est loin des 2^^128...&lt;br /&gt;&lt;br /&gt;En résumé, c'est une approchoe time / memory tradoff 100% mémory :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-8837428303682967959?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/8837428303682967959/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=8837428303682967959' title='2 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8837428303682967959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8837428303682967959'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/12/reverse-md5.html' title='Reverse MD5'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-6650683013596901654</id><published>2006-12-07T12:15:00.000+01:00</published><updated>2006-12-19T12:18:30.091+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gentoo'/><title type='text'>Gentoo sur la PS3</title><content type='html'>Dans la famille "Tchötégik", voici un petit cookbook sur &lt;span style="font-style:italic;"&gt;"Comment installer une Gentoo sur sa PS3"&lt;/span&gt; : &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;a href="http://whitesanjuro.googlepages.com/"&gt;&lt;br /&gt;http://whitesanjuro.googlepages.com/&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;L'intérêt, en plus d'être purement académique car les jeux ne tournent pas (encore) sur cet OS et d'étudier le hardware contenu dans la console, est plutôt de démontrer la flexibilité de Gentoo à s'adapter à n'importe quel type d'environnement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-6650683013596901654?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/6650683013596901654/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=6650683013596901654' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6650683013596901654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6650683013596901654'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/12/gentoo-sur-la-ps3.html' title='Gentoo sur la PS3'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-4251741217511830946</id><published>2006-12-06T11:50:00.000+01:00</published><updated>2006-12-06T11:59:24.441+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>Une nouvelle bulle internet en formation ?</title><content type='html'>Cette question défraie la chronique ces jours, et j'ai trouvé qu'elle méritait un petit article. Non pas pour en expliquer les raisons ou essayer de deviner la date de son éclatement, d'autre le font mieux que moi, mais parce que je suis tombé sur la citation suivante : &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;L’avantage avec les bulles [économique], c’est qu’elles peuvent toujours se dégonfler avant d’éclater.&lt;br /&gt;Mais l’inconvénient avec les bulles, c’est que les gens croient &lt;span style="font-weight:bold;"&gt;vraiment&lt;/span&gt; qu’elles peuvent se dégonfler avant d’éclater...&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Qui, bien qu'amusante, a le mérite d'être entièrement fondée à l'heure ou les entreprises 2.0 sont formées sur une base de levée de fonds dans le seul but d'être revendue dès l'ombre du début d'un éventuel profit à l'horizon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-4251741217511830946?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/4251741217511830946/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=4251741217511830946' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4251741217511830946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4251741217511830946'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/12/une-nouvelle-bulle-internet-en.html' title='Une nouvelle bulle internet en formation ?'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2690334453584503572</id><published>2006-11-29T09:29:00.000+01:00</published><updated>2006-12-19T12:18:33.682+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Recrutement Google, étape #2</title><content type='html'>Mardi 28 novembre je me suis rendu dans les locaux de Google à Zürich afin de procéder à la suite du processus de recrutement. L'heure de rendez-vous, fixée à 10h00, n'étant pas trop contraignante, j'ai pris le train à Neyruz à 07h45 pour arriver à 09h38 à Zürich, et finalement 9h45 à Freigutstrasse 12, 8002 Zurich.&lt;br /&gt;&lt;br /&gt;Le bâtiment est une ancienne banque privée, de couleur rosé et dont le style s'apparenterait au début du 20ème siècle. La porte d'entrée est fermée à clé, et il faut s'annoncer avant de pouvoir entrer. Puis une fois à l'intérieur, il faut s'inscrire sur un terminal et signer sur une tablette, et un badge autocollant est directement imprimé.&lt;br /&gt;&lt;br /&gt;L'intérieur du bâtiment est plutôt blanc, avec du parquet sur le sol, mais ce qui frappe c'est les accessoires (poufs, ballons, coussins) de couleurs vives disposés un peu partout. On se croirait en plein jardin d'enfants. Seul les 2 écrans 20 pouces par place de travail rappellent qu'on est bien dans une entreprise de services.&lt;br /&gt;&lt;br /&gt;Ma journée s'est composée de 4 entretiens techniques et d'un repas avec Peter, un des deux ingénieurs qui m'avait interviewé à l'EPFL.&lt;br /&gt;&lt;br /&gt;Les questions posées étaient de nouveau très algorithmiques, principalement axées sur l'organisation des données en &lt;a href="http://fr.wikipedia.org/wiki/Arbre_%28informatique%29"&gt;arbre&lt;/a&gt; ou &lt;a href="http://fr.wikipedia.org/wiki/Table_de_hashage"&gt;table de hashage&lt;/a&gt;, tout en tenant compte de l'ordre de &lt;a href="http://fr.wikipedia.org/wiki/Complexit%C3%A9_algorithmique"&gt;complexité&lt;/a&gt; des fonctions proposées.&lt;br /&gt;&lt;br /&gt;Un exercice a retenu mon attention et je souhaite vous en faire partager mon expérience :&lt;br /&gt;&lt;br /&gt;La donnée est simple : un personne se tient en bas d'un escalier de &lt;span style="font-style:italic;"&gt;N&lt;/span&gt; marches. A chaque pas, il peut monter une ou deux marches. Combien de possibilités de configuration de trajets différents a-t-il pour monter l'escalier ?&lt;br /&gt;&lt;br /&gt;L'illustration ci-dessous schématise le problème.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger2/4843/610528889700645/1600/385104/Presentation1.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/x/blogger2/4843/610528889700645/400/858082/Presentation1.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Le raisonnement approprié pour ce problème est de se dire que pour atteindre une marche &lt;span style="font-style: italic;"&gt;n&lt;/span&gt;, la seule possibilité est d'être passé par la marche &lt;span style="font-style: italic;"&gt;n-1&lt;/span&gt; ou &lt;span style="font-style: italic;"&gt;n-2&lt;/span&gt;, et donc le nombre de chemin pour arriver sur la marche &lt;span style="font-style: italic;"&gt;n&lt;/span&gt; est la somme des possibilités d'arriver sur les cases &lt;span style="font-style: italic;"&gt;n-1&lt;/span&gt; et &lt;span style="font-style: italic;"&gt;n-2&lt;/span&gt;.&lt;br /&gt;On a donc la formule de récurrence suivante :&lt;br /&gt;&lt;i&gt;F&lt;/i&gt;&lt;sub&gt;&lt;i&gt;n&lt;/i&gt;&lt;/sub&gt; = &lt;i&gt;F&lt;/i&gt;&lt;sub&gt;&lt;i&gt;n&lt;/i&gt; − 1&lt;/sub&gt; + &lt;i&gt;F&lt;/i&gt;&lt;sub&gt;&lt;i&gt;n&lt;/i&gt; − 2&lt;/sub&gt;&lt;br /&gt;qui devrait nous faire penser à la &lt;a href="http://fr.wikipedia.org/wiki/Suite_de_Fibonacci"&gt;suite de Fibonacci&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;La suite de la question est simplement : comment peut-on calculer de manière efficace une telle suite ? &lt;br /&gt;&lt;br /&gt;Il est possible de calculer une suite de Fibonacci de manière itérative, et donc d'une complexité de O(n), mais ce que je ne savais pas c'est qu'il existe une manière encore plus efficace pour calculer en O(log(n)) !&lt;br /&gt;&lt;br /&gt;Cette solution repose sur deux propriétés : l'expression matricielle du problème, et le calcul de puissance. &lt;br /&gt;&lt;br /&gt;La suite de Fibonacci peut donc s'exprimer sous la forme matricielle suivante : &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger2/4843/610528889700645/1600/884589/1444d651825efd79f133cfc7199607ba.png"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/x/blogger2/4843/610528889700645/400/307759/1444d651825efd79f133cfc7199607ba.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ce qui nous amène à l'expression suivante : &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger2/4843/610528889700645/1600/518892/f47629e23da76388b10ff33b58b0c8f1.png"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/x/blogger2/4843/610528889700645/400/927758/f47629e23da76388b10ff33b58b0c8f1.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;On voit apparaitre un matrice 2x2 élevée à la puissance &lt;span style="font-style:italic;"&gt;n&lt;/span&gt;. On peut donc utiliser l'algorithme &lt;span style="font-style:italic;"&gt;square-and-multiply&lt;/span&gt; (donné ci-dessou) pour la calculée, qui lui est en O(log(n)).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger2/4843/610528889700645/1600/19531/f5b1ee5581ec34be8704d1ab0a6ebec2.png"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/x/blogger2/4843/610528889700645/400/620519/f5b1ee5581ec34be8704d1ab0a6ebec2.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;CQFD. Des questions ? Des remarques ?&lt;br /&gt;&lt;br /&gt;Je suis reparti vers 15h30, fatigué mais content. Je devrais avoir une réponse dans le courant de la semaine prochaine quant à leur envie de m'engager ou pas.&lt;br /&gt;&lt;br /&gt;Suite au prochain (et peut-être dernier) épisode...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2690334453584503572?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2690334453584503572/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2690334453584503572' title='1 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2690334453584503572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2690334453584503572'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/11/recrutement-google-tape-2.html' title='Recrutement Google, étape #2'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-4684361966179075875</id><published>2006-11-24T09:31:00.000+01:00</published><updated>2006-12-19T12:20:46.002+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>I'm the 58,920,569 richest person on earth!</title><content type='html'>Avec mon revenu actuel tout à fait moyen pour la Suisse (un peu moins de 4000.- brut / mois), je fais partie des 1% personnes les plus riches du monde, d'après le site &lt;a href="http://www.globalrichlist.com/"&gt;GlobalRichList&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Imaginez ce que ça sera quand je toucherai mon salaire de ministre ;)&lt;br /&gt;&lt;br /&gt;Plus sérieusement, voici une preuve criante que les richesses sont mal réparties. &lt;br /&gt;&lt;br /&gt;Arriverons-nous à faire en sorte que la fossé qui sépare les riches des autres ne s'élargisse pas trop ? Un défi pour l'avenir autant important que l'environnement...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-4684361966179075875?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/4684361966179075875/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=4684361966179075875' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4684361966179075875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4684361966179075875'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/11/im-58920569-richest-person-on-earth.html' title='I&apos;m the 58,920,569 richest person on earth!'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5990977137738461834</id><published>2006-11-22T13:31:00.000+01:00</published><updated>2006-12-19T12:18:36.544+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gentoo'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Bug de l'an 2038</title><content type='html'>Le format Unix pour les dates, c'est-à-dire le nombre de secondes depuis le 1er janvier 1970, est une très bonne chose car ça représentation est très compact, on peut facilement comparer 2 dates, calculer des intervalles, etc.&lt;br /&gt;&lt;br /&gt;Le seul problème qui en découle est que son implémentation sous forme d'entier, 32 bits sur la majorité des systèmes actuels, et condamné à subir un &lt;span style="font-style:italic;"&gt;integer overflow&lt;/span&gt;, et ce dans un peu plus de (2^^32 / 3600 / 24 / 365  =) 136 ans à partir de la date de référence si la date est codée en entier non signé, (2^^31 / 3600 / 24 / 365 =) 68 ans si le codage est signé, c'est-à-dire vers l'an 2106 ou 2038 respectivement.&lt;br /&gt;Il nous reste de beaux jours devant nous, mais cela montre à quel point on est incapable de ne pas reproduire le bug de l'an 2000...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5990977137738461834?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5990977137738461834/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5990977137738461834' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5990977137738461834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5990977137738461834'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/bug-de-lan-2038.html' title='Bug de l&apos;an 2038'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5133959624170551978</id><published>2006-11-17T08:17:00.000+01:00</published><updated>2006-12-19T12:18:58.134+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Quand Internet remplace les systèmes experts</title><content type='html'>Un article paru dans &lt;a href="http://www.infos-du-net.com"&gt;Info-du-net&lt;/a&gt; parlant de &lt;a href="http://www.infos-du-net.com/actualite/8847-diagnostic-google.html"&gt;l'élaboration de diagnostiques pour des maladies&lt;/a&gt; montre à quel point la base de données "Internet" peut devenir utile en cas d'utilisation judicieuse : &lt;br /&gt;&lt;br /&gt;Un système expert est une base de données de règles et de conditions qui nous amène, en posant des questions sur les symptômes, à un diagnostique précis du problème. C'est donc une base de données contenant tous les symptômes possibles, avec des relations entre eux, que l'on peut questionner. Un système expert n'est utile que si il contient une liste exhaustive des symptômes.&lt;br /&gt;&lt;br /&gt;On remarque donc directement une ressemblance frappante avec Internet (ou du moins un moteur de recherche tel que Google) : une base de données que l'on peut questionner.&lt;br /&gt;&lt;br /&gt;Internet devient donc un système expert grâce à la contribution des gens dans leurs domaines d'application. Toutefois la différence entre un système expert et Internet, c'est que la base du premier est constituée par des spécialistes et, si elle n'est pas exhaustive, elle est au moins fiable, alors que n'importe bien que la base Internet se met à jour en temps réel, n'importe qui peut y contribuer, même ceux qui n'y connaissent rien au domaine...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5133959624170551978?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5133959624170551978/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5133959624170551978' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5133959624170551978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5133959624170551978'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/11/quand-internet-remplace-les-systmes.html' title='Quand Internet remplace les systèmes experts'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-9174673624163782085</id><published>2006-11-16T07:58:00.000+01:00</published><updated>2006-12-19T12:19:03.689+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Entretien d'embauche avec Google</title><content type='html'>Les RH de Google m'ont contacté il y a maintenant 3 semaines afin de me faire passer la première étape de leur entretien d'embauche.&lt;br /&gt;&lt;br /&gt;L'interview, technique, c'est déroulé en 2 parties de 45 minutes chacune, durant lesquelles un ingénieur Google m'a posé des questions techniques. Apparemment il n'y avait pas un nombre défini de questions, mais tant qu'une réponse jugé satisfaisante était trouvée, on passait à une autre, inventée &lt;span style="font-style: italic;"&gt;on the fly&lt;/span&gt; mais en relation avec notre CV.&lt;br /&gt;&lt;br /&gt;Voici un petit aperçu des 10 questions auxquelles j'ai réussi à répondre. Elles sont traduites en franglais_geek1 pour les besoins du billet, et je n'y fait figurer que celles que j'ai trouvé intéressantes ou qui sont faciles d'exposer sur un blog  :&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Implémentez en C la fonction &lt;span style="font-style: italic;"&gt;assert(i &amp;gt; 0)&lt;/span&gt; de manière à ce que la condition "&lt;span style="font-style: italic;"&gt;i &amp;gt; 0&lt;/span&gt;" soit affichée en cas d'erreur&lt;/li&gt;&lt;li&gt;Même chose en C++, afin que le code suivant soit bien formé :&lt;br /&gt;&lt;span style="font-style: italic;"&gt;assert(i &amp;gt; 0) &amp;lt;&amp;lt; "message" &amp;lt;&amp;lt; i ;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Triez un tableau d'un million d'entier (&lt;span style="font-style: italic;"&gt;int&lt;/span&gt; sur 4 &lt;span style="font-style: italic;"&gt;bytes&lt;/span&gt;) stockée sur un disque dur en ne disposant qu'une mémoire de 2 MB. Comment vous y prenez vous ?&lt;/li&gt;&lt;li&gt;Implémentez une classe qui contient 3 méthodes :&lt;br /&gt;- &lt;span style="font-style: italic;"&gt;void push(int)&lt;/span&gt;&lt;br /&gt;- &lt;span style="font-style: italic;"&gt;int pop()&lt;/span&gt;&lt;br /&gt;- &lt;span style="font-style: italic;"&gt;int minimum()&lt;/span&gt;&lt;br /&gt;dont les 3 méthodes s'exécute avec une complexité en &lt;span style="font-style: italic;"&gt;O(1)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Trouvez une méthode efficace qui permet de détecter une boucle dans une liste chainée, sans pouvoir modifier les éléments de la liste ni recopier en entier la liste.&lt;/li&gt;&lt;/ol&gt;Les questions sont posées sans temps de préparation, ni ordinateur ou autres documents d'aide. On remarquera que les réponses, une fois connue, ne sont pas si compliquées qu'elles en auraient l'air.&lt;br /&gt;&lt;br /&gt;1. Première hypothèse, avant que l'expert ne précise que la condition "i &gt; 0" doit être affichée :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;void assert (int cond) { &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;if (cond == 0) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf("Erreur");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit(1);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Le problème se corse quand il s'agit d'afficher textuellement "i &gt; 0", car en passant par un argument, il sera évalué avant d'être passer par valeur, donc on perd toute chance de pouvoir l'afficher. Ma deuxième version en passant un pointeur de fonction en paramètre s'est vite avérée fastidieuse, et l'idée d'utiliser par une marco et ses possibilités de manipulation de strings m'a soudain frappée, pour finalement donner quelque chose :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;#define assert(cond) if ((cond) == 0) { \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;printf("Erreur "); \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;printf(#(cond)); \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;exit(1); \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;2. Une fois la première question complétée, la deuxième est devenue triviale : il suffit d'ajouter &lt;span style="font-style: italic;"&gt;cout &lt;/span&gt;à la fin de la macro pour que si la condition était différente de 0, on continue avec &lt;span style="font-style: italic;"&gt;cout&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;#define assert(cond) if ((cond) == 0) { \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;printf("Erreur "); \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;printf(#(cond)); \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;exit(1); \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;} \&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;cout&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;3. 1 million d'entiers sur 4 bytes nous fait 4MB, donc trop pour tenir en entier dans la mémoire. Il faut donc partager le tableau en 2, trier chaque partie en utilisant n'importe quel algorithme de tri, puis fusionner les 2 tableaux à l'aide d'un tri par fusion.&lt;br /&gt;&lt;br /&gt;4. La complexité en O(1) nous suggère directement l'utilisation d'une liste chainée. Push et pop deviennent donc trivial, push ajoute l'élément à en tête de liste, pop retourne en enlève le premier élément de la liste.&lt;br /&gt;Le problème se pose maintenant pour la méthode qui retourne le minimum, qui est doit aussi se faire en O(1). Il est donc impossible de faire une recherche, car aucune méthode de recherche n'est en O(1). L'idée est donc de maintenir une deuxième liste chainée qui contiendra ces minimums. Donc on modifie push pour tester si la valeur à ajouter est plus petite OU EGALE au minimum, et si c'est le cas on ajoute aussi l'élément dans la liste des minimums, et pop pour enlever l'élément de la liste des minimums si cet élément est le minimum.&lt;br /&gt;&lt;br /&gt;En pseudo Java ça nous donne quelque chose du style :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;LinkedList&lt;integer&gt; l;&lt;/integer&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;LinkedList&lt;integer&gt; m;&lt;/integer&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;void push (int e)  {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;if (e &lt;= m.top()) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m.push(e);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;l.push(e);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int pop() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;int e = l.pop();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;if (e == l.top()) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;l.pop();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;return e;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;int minimum() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;nbsp;&amp;nbsp;return m.top();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;5. La solution trivial qui est de marquer les noeuds parcourus n'est pas envisageable, car elle sous-entendrait de modifier le contenu des noeuds, ce qui n'est justement pas possible.&lt;br /&gt;Une bonne solution est donc d'inverser les liens en parcourant la liste, et si on revient au noeud initial on sera sûr d'avoir une boucle. En parcourant la liste dans l'ordre inverse et en réinversant les liens, il est possible de remettre la liste dans l'état qu'on avait avant de débuter la recherche. A noter qu'il est impératif de s'assurer qu'un seul processus n'accède à la liste en simultané, car durant la recherche la liste est modifiée.&lt;br /&gt;&lt;br /&gt;2 entretiens sur 6, prochain épisode pour bientôt j'espère...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-9174673624163782085?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/9174673624163782085/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=9174673624163782085' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/9174673624163782085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/9174673624163782085'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/11/interview-dembauche-chez-google.html' title='Entretien d&apos;embauche avec Google'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-1076051645449968494</id><published>2006-11-08T14:37:00.000+01:00</published><updated>2006-11-08T14:43:38.426+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>PHP Multithread</title><content type='html'>Non, faire tourner PHP en multithread n'est pas un mythe !&lt;br /&gt;C'est possible de lancer des processus fils grâce au module &lt;span style="font-style:italic;"&gt;pcntl&lt;/span&gt;, et à les synchroniser avec le module &lt;span style="font-style:italic;"&gt;sémaphore&lt;/span&gt;, de préférence en ligne de commande (la doc précise que leur utilisation en module apache peut amener à des résultats erronés).&lt;br /&gt;&lt;br /&gt;Voici donc un petit article qui démontre par un exemple comment implémenter un &lt;a href="http://www.noisette.ch/wiki/index.php/PHP/Multithread"&gt;démon multithread en PHP&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-1076051645449968494?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/1076051645449968494/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=1076051645449968494' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1076051645449968494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1076051645449968494'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/11/php-multithread.html' title='PHP Multithread'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-6350917696419286254</id><published>2006-10-11T08:24:00.000+02:00</published><updated>2006-10-11T08:25:59.847+02:00</updated><title type='text'>Covoiturage</title><content type='html'>Premier jour de covoiturage. Tout c’est bien passé, à part une petite frayeur dans un bouchon.&lt;br /&gt;&lt;br /&gt;Je ne peux pas encore me prononcer sur les effets à long terme du covoiturage, mais j’ai déjà trouvé que c’était plus sympa le trajet à 2. L'heure de trajet est passée bien plus  vite, et suivant les personnes qui accompagnent, les échanges peuvent être intéressants et constructifs. &lt;br /&gt;&lt;br /&gt;Dès la semaine prochaine on charge 2 personnes supplémentaires.&lt;br /&gt;&lt;br /&gt;On a l’air vachement moins égoïste à 2-3 dans une voiture…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-6350917696419286254?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/6350917696419286254/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=6350917696419286254' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6350917696419286254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6350917696419286254'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/10/covoiturage.html' title='Covoiturage'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2221814101363609258</id><published>2006-10-11T07:53:00.000+02:00</published><updated>2006-12-19T12:19:06.696+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gentoo'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Un serveur en overload</title><content type='html'>Quels sont les signes qu'un serveur est en overload ?&lt;br /&gt;&lt;br /&gt;La réponse est relativement simple un outil de monitoring tel que &lt;a href="http://oss.oetiker.ch/mrtg/"&gt;mrtg&lt;/a&gt; ou maintenant &lt;a href="http://oss.oetiker.ch/rrdtool/"&gt;rrdtool&lt;/a&gt; est installé sur le serveur.&lt;br /&gt;&lt;br /&gt;Considérons le graphique suivant : &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.noisette.ch/wiki/index.php/Image:Cpu0-year2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px;" src="http://www.noisette.ch/wiki/index.php/Image:Cpu0-year2.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Il représente la charge d'un serveur sur une moyenne journalière, avec en y le % de charge. Dès juillet, l'augmentation de la charge non négligeable que subit le serveur est un signe qu'il faut envisager rapidement un remplacement par une machine plus puissante. L'augmentation est linéaire, elle nous permet donc une bonne projection et donc une bonne prévision de quand le serveur arrivera à une charge moyenne de 100%.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2221814101363609258?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2221814101363609258/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2221814101363609258' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2221814101363609258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2221814101363609258'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/10/un-serveur-en-overload.html' title='Un serveur en overload'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-7589113520635794541</id><published>2006-10-10T22:54:00.000+02:00</published><updated>2006-09-29T07:54:38.092+02:00</updated><title type='text'>Les billets de mon ancien blog</title><content type='html'>Comme je l'ai dit ici, je compte utiliser régulièrement ce blog. Et en fonction du temps disponible, je vais faire revivre d'ancien billet qui sont partis aux oubliettes en même temps que mon ancien blog.&lt;br /&gt;&lt;br /&gt;Ne soyez donc pas surpris de voir des billets qui commencent par "Initialement posté sur Noisette.ch", ce billet vont s'entremêler aux nouveaux.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-7589113520635794541?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/7589113520635794541/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=7589113520635794541' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7589113520635794541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/7589113520635794541'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/10/les-billets-de-mon-ancien-blog.html' title='Les billets de mon ancien blog'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-3619182781237963137</id><published>2006-10-02T11:51:00.001+02:00</published><updated>2006-10-02T11:51:23.505+02:00</updated><title type='text'>Linked In</title><content type='html'>Après avoir reçu plusieurs invitations d'amis et collègues, j'ai finalement rejoins la grande famille de LinkdeIn, sur lequel vous pouvez consulter mon profile et mes connexions : &lt;a href="http://www.linkedin.com/in/benoitperroud"&gt;http://www.linkedin.com/in/benoitperroud&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Je ne sais pas encore si ce site va me servir pour trouver un futur emploi, mais j'ai trouvé le concept intéressant, et je compte bien arriver à plus de 90% dans toutes les options :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-3619182781237963137?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3619182781237963137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3619182781237963137'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/10/linked-in.html' title='Linked In'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-969192373952229470</id><published>2006-09-29T08:45:00.000+02:00</published><updated>2006-12-19T12:19:12.654+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><title type='text'>Les algorithmes de recherche binaire et par fusion sont bogués</title><content type='html'>C'est la constatation alarmante qu'a fait Joshua Bloch, Software développeur chez Google, dans son article &lt;a href="http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it-nearly.html"&gt;Nearly All Binary Searches and Mergesorts are Broken&lt;/a&gt; (Presque tous les algorithme de recherche binaire et par fusion sont bogués) et il en explique précisément la cause. &lt;br /&gt;&lt;br /&gt;Il cite en exemple la méthode binarySearch de la librairie java.util.Arrays, qu'il a lui même écrit avant de quitter Sun.&lt;br /&gt;&lt;br /&gt;La ligne contenant ce bug est la suivante : &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;int mid = (low + high) / 2;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Le bug en question est un "bête" integer overflow qui peut apparaître si on manipule un tableau de l'ordre de plus de 2^30 éléments.&lt;br /&gt;&lt;br /&gt;Le plus dérangeant dans cette histoire banale est que ce genre de bug, pourtant trouvé dans une routine de peu de lignes, est passé inaperçu pendant près de 60 ans. &lt;br /&gt;&lt;br /&gt;Cet exemple démontre très précisément qu'il est impossible d'écrire du code sans bugs, et que donc les prochaines améliorations seront plus d'en limiter les conséquences que de les éradiquer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-969192373952229470?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/969192373952229470/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=969192373952229470' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/969192373952229470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/969192373952229470'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/les-algorithmes-de-recherche-binaire-et.html' title='Les algorithmes de recherche binaire et par fusion sont bogués'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5616924052124918211</id><published>2006-09-26T08:10:00.001+02:00</published><updated>2006-11-22T09:20:20.965+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gentoo'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Gentoo avec Apache2 + PHP5 + Suexec + FastCGI (dynamic)</title><content type='html'>FastCGI est un concept tout à fait intéressant qui permet, dans le cadre de PHP, d'allier rapidité et sécurité. Il permet conjointement d'avoir la rapidité de mod_php avec la sécurité de PHP/CGI, notemment en terme de droits d'utilisateurs.&lt;br /&gt;Je ne vais pas vous refaire une série de benchmark comme c'est le cas sur beaucoup d'autre site, mais je viens de réaliser un article explicant en détail l'installation, la configuration et surtout les problèmes qu'on peut rencontrer avec la mise en place PHP, FastCGI dynamique et Suexec :&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;a href="http://www.noisette.ch/wiki/index.php/Apache2_php_fast_cgi_suexec_dynamic"&gt;Configuration de PHP avec FastCGI et Suexec pour Apache2&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5616924052124918211?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5616924052124918211/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5616924052124918211' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5616924052124918211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5616924052124918211'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/gentoo-avec-apache2-php5-suexec-fastcgi.html' title='Gentoo avec Apache2 + PHP5 + Suexec + FastCGI (dynamic)'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-73357863207273301</id><published>2006-09-26T08:10:00.000+02:00</published><updated>2006-11-22T09:22:43.028+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>Pourquoi les mots "Chers Concitoyens"</title><content type='html'>&lt;span lang="FR-CH"&gt;Je ne souhaite pas vraiment m'étendre sur des discours politiques car ceux-ci ne sont pas ma tasse de thé, et encore moins dans l'esprit que je compte tenir sur mon blog.&lt;br /&gt;&lt;br /&gt;Mais au lendemain des votations fédérales sur le durcissement du droit d'asile, le préfix "con" du terme concitoyens retrouve tout son sens.&lt;/span&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;&lt;span lang="FR-CH"&gt; La question est donc lancée : « Mais qu’avez-vous donc fait ? ». Seul l’avenir nous le dira...&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-73357863207273301?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/73357863207273301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/73357863207273301'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/pourquoi-les-mots-chers-concitoyens.html' title='Pourquoi les mots &quot;Chers Concitoyens&quot;'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2139304812460468262</id><published>2006-09-21T08:08:00.000+02:00</published><updated>2006-11-22T09:36:42.782+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='epfl'/><title type='text'>Mes cours de Master : terminés</title><content type='html'>Alors que mon travail de diplôme est déjà bien entamé, je voulais juste m'arrêter un peu sur mes résultats du Master à l'&lt;a href="http://www.epfl.ch"&gt;EPFL&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Le détail des notes peut être trouvé sur mon site : &lt;a href="http://www.noisette.ch/wiki/index.php/EPFL/Credits_master"&gt;Mes notes de Master&lt;/a&gt;, et il y a 2 choses importantes à relever : 5.57 de moyenne (sur 6) sur l'année, et aucune note en dessous de 5.&lt;br /&gt;&lt;br /&gt;Ce que j'aimerais montrer par là, ce n'est pas combien je suis fort et tout, loin de moi cette idée narcissique, mais plutôt qu'avec de la &lt;span style="font-weight: bold;"&gt;motivation&lt;/span&gt; et de la &lt;span style="font-weight: bold;"&gt;persévérance&lt;/span&gt;, on arrive à nos fins (et en passant faire un clin d'oeil à certains détracteurs du redoublement dans les universités, mais une réponse plus complète viendra peut-être dans un autre billet, intitulé quelque chose comme "L'apprentissage par l'échec").&lt;br /&gt;&lt;br /&gt;La motivation est une capacité merveilleuse dont nous a dotés mère Nature, grâce à laquelle on peut bouger des montagnes. La motivation donne des ailes, décuple les forces, mais ne serait qu'un feu de paille si la persévérance ne prenait pas la relève. La persévérance, elle, est plutôt une discipline de vie, une force mentale qui, si elle est utilisée à outrance, se transforme rapidement en obstination.&lt;br /&gt;&lt;br /&gt;J'ai appris, après deux échecs, à dompter ma motivation, puis j'ai cultivé ma persévérance pour finalement arriver là ou j'en suis aujourd'hui, en train de faire mon travail de diplôme dans le groupe &lt;a href="http://www.kudelski.com"&gt;Kudelski&lt;/a&gt;. Et je suis convaincu que refaire la deuxième année était pour moi la meilleure chose, tant cette année est importante sur le plan théorique. Finir une branche avec juste la moyenne, c'est suffisant, mais à mes yeux actuels ça n'est pas assez pour prétendre avoir compris les finesses de la matière et pouvoir tisser des liens avec d'autres branches. J'ai réussi à le faire grâce au travail, et ça se ressent à beaucoup de niveaux.&lt;br /&gt;&lt;br /&gt;Le travail n'est pas une source de frustration, bien au contraire. Et la recette en est bien simple :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Immergez-vous dans un projet,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Adoptez un état d'esprit positif et la motivation grandira d'elle-même,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Fixez-vous des objectifs à court et moyen terme pour favoriser la persévérance.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2139304812460468262?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2139304812460468262/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2139304812460468262' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2139304812460468262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2139304812460468262'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/mes-cours-de-master-termins.html' title='Mes cours de Master : terminés'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-9189028618525765727</id><published>2006-09-20T08:08:00.000+02:00</published><updated>2006-12-19T12:19:17.165+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Système de réécriture d'URL (URL Rewriting)</title><content type='html'>Les systèmes de réécriture d'URL posent rapidement des problèmes de scalabilité pour un site générant un trafic respectable (genre dès 1000 visiteurs uniques par jour).  Je l'ai déjà exprimé dans un précédent article : &lt;a href="http://benoitperroud.blogspot.com/2006/09/404-sef-un-mode-mambo-gnial-en.html"&gt;Mambo 404 SEF&lt;/a&gt;, et souhaite maintenant apporter un design de solution.&lt;br /&gt;&lt;br /&gt;Une technique relativement simple pour palier à ce problème de VARCHAR non- ou mal -indexable est d'introduire une variable aléatoire dans l'URL, variable à partir de laquelle la vrai URL sera chargée : &lt;span style="font-style: italic;"&gt;www.domaine.com/&lt;/span&gt;&lt;span style="font-style: italic;"&gt;14523623423/news/ma_premiere_news.html&lt;/span&gt;&lt;br /&gt;L'important dans cet URL est donc la variable 14523623423, alors que ce qui se situe après n'a aucune importance et peut être modifié à souhait (on remarque aussi ici que cette technique permet rapidement de mettre un place de l'URL flooding, utilisants des URLs de toute sorte pour pointer sur la même page. Attention à ne pas en abuser, car on risque de voir son site se faire bannir des moteurs de recherche).&lt;br /&gt;&lt;br /&gt;La requête SQL devient donc&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SELECT realurl FROM &lt;/span&gt;&lt;span style="font-family:courier new;"&gt;redirections WHERE urlid = &lt;/span&gt;&lt;span style="font-family:courier new;"&gt;14523623423&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Mieux ça non ? Le problème évoqué ici est en fait global à tout design de base de données : les champs utilisés sans intervention d'un utilisateur dans une condition devraient toujours être de type entier ou un dérivé. Car même si les chaines de caractères sont relativement rapide lors des tests, la réaction à haute charge est très souvent mauvaise...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-9189028618525765727?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/9189028618525765727/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=9189028618525765727' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/9189028618525765727'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/9189028618525765727'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/systme-de-rcriture-durl-url-rewriting.html' title='Système de réécriture d&apos;URL (URL Rewriting)'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-8926090102351615542</id><published>2006-09-16T08:06:00.000+02:00</published><updated>2006-09-29T08:06:59.154+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>La vie d'un Troll</title><content type='html'>Un Troll, en informatique, est une polémique acharnée et sans fin (souvent sur un forum ou une mailing liste). La nature du Troll n'est jamais constructive , et, comme le disait &lt;a href="http://standblog.org/blog/2006/07/10/93114852-reponse-a-la-tribune-il-n-a-de-libre-que-le-nom-parue-dans-libe"&gt;Tristan Nitot&lt;/a&gt;, le Troll ne grossit que si on le nourrit. Si on l'ignore il se meurt de lui-même.&lt;br /&gt;&lt;br /&gt;Le nom Troll vient d'analogies aux mondes fantatstiques, notamment Donjon et Dragon dans lequel les Trolls ont une grande capacité de régénération.&lt;br /&gt;&lt;br /&gt;Si vous voyez un Troll, partez en courant. Au mieux il ne vous fera que perdre du temps...&lt;br /&gt;&lt;br /&gt;Explication du &lt;a href="http://maester.over-blog.com/article-2900464-6.html"&gt;Troll en DB&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-8926090102351615542?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/8926090102351615542/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=8926090102351615542' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8926090102351615542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/8926090102351615542'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/la-vie-dun-troll.html' title='La vie d&apos;un Troll'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-1919088551177703521</id><published>2006-09-15T08:05:00.000+02:00</published><updated>2006-11-22T09:23:14.481+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='epfl'/><title type='text'>Les quinze jours décisifs des cours à option</title><content type='html'>&lt;span style="font-style: italic;"&gt;Texte à paraître dans la brochure de valorisation du Collège des Humanités de l'EPFL&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Le processus de décision qui conduit les étudiants à choisir tel ou tel cours à option, au terme des deux semaines qui précèdent l’inscription définitive, est loin d’être aussi anecdotique qu’il n’y paraît. En effet, de tels libres choix ont souvent une influence décisive sur l’orientation future d’une carrière.&lt;br /&gt;&lt;br /&gt;Un sérieux instrument statistique à l’appui, les six auteurs de l’étude ont interpellé leurs camarades sur la perception de leurs propres compétences face au cours envisagé, l’intérêt suscité, l’utilité estimée, les qualités du professeur, la difficulté du cours, le degré d’autonomie et les liens sociaux entretenus entre étudiants. 62 personnes, soit 43 hommes et 19 femmes, ont répondu. Cette enquête devrait éclairer les processus de décision mais aussi offrir aux enseignants un outil de réflexion sur les moyens à leur disposition pour stimuler la motivation intrinsèque des étudiants, sans laquelle il n’y a pas d’apprentissage optimal.&lt;br /&gt;&lt;br /&gt;La première bonne nouvelle qui se dégage des résultats obtenus repose sur le fait que les étudiants opèrent majoritairement des choix qui épousent au mieux leur plaisir et leur intérêt. Les chiffres sont éloquents : la volonté de maîtriser un nouveau domaine qui séduit, donc de relever un nouveau défi, passe nettement avant des objectifs de performance liés à des critères de type utilitaire.&lt;br /&gt;&lt;br /&gt;Mais l’un des points les plus intéressants que l’étude met au jour concerne les étudiants dits « faiblement auto-efficaces », c’est-à-dire ceux qui doutent de leur capacité à maîtriser une branche. Face à ce « public réticent », les professeurs sont capables de renverser la vapeur et de convaincre durant ces deux semaines cruciales, mais à trois conditions : qu’ils clarifient les buts du cours, favorisent le comportement autonome de leurs étudiants et privilégient l’écoute de leurs besoins personnels. C’est effectivement autour de ces trois axes que s’articule l’auto-détermination des étudiants, caractérisée par le goût du risque, une ouverture plus grande à l’apprentissage, et donc une motivation plus élevée.&lt;br /&gt;&lt;br /&gt;Tiré de : &lt;b&gt;L’influence des deux premières semaines de cours, avant l’inscription définitive, sur la motivation autonome des étudiants à choisir un cours et le rôle de l’auto-efficacité dans ce choix&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Auteurs : Loana Chatelain,Benoît Perroud, étudiant en informatique&lt;br /&gt;Laura Derksen, Sarah Emery, François-Xavier Meuwly, étudiants en mathématiques&lt;br /&gt;Guillaume Schmit, étudiant en microtechnique&lt;br /&gt;&lt;br /&gt;Sous la direction de Fabrizio Butera et Régis Scheidegger, faculté des sciences sociales et politiques, Université de Lausanne&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-1919088551177703521?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1919088551177703521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1919088551177703521'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/les-quinze-jours-dcisifs-des-cours.html' title='Les quinze jours décisifs des cours à option'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5168890059244723528</id><published>2006-09-15T08:04:00.001+02:00</published><updated>2006-11-22T09:21:52.389+01:00</updated><title type='text'>Comment gagner à l'Euromillion</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.noisette.ch/wiki/images/Euromillion.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px;" src="http://www.noisette.ch/wiki/images/Euromillion.jpg" alt="" border="0" /&gt;&lt;/a&gt;Ou plutôt : Quels numéros jouer à la loterie ?&lt;br /&gt;&lt;br /&gt;Si j'étais un joueur de loterie assidu, mon principal problème serait de trouver chaque semaine des numéros différents pour compléter mon année de naissance et celle de ma copine. Cette semaine, je serais tenté de jouer des numéros comme le 2, 4, 21 ou 37, car le Pape est mort le 2 du 4 à 21h37.&lt;br /&gt;&lt;br /&gt;Mais l'idée d'utiliser &lt;a href="http://www.random.org/"&gt;random.org&lt;/a&gt; m'est apparue en écrivant un autre article (&lt;a href="http://www.noisette.ch/wiki/index.php/Espace_administration_par_email"&gt;Un espace d'administration par email&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Quoi de mieux que de se faire générer ses numéros par un vrai générateur aléatoire ?&lt;br /&gt;&lt;br /&gt;Pour l'Euromillion par exemple, essayez :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.random.org/cgi-bin/randnum?num=5&amp;col=1&amp;amp;min=1&amp;max=50"&gt;les 5 numéros&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.random.org/cgi-bin/randnum?num=2&amp;amp;amp;col=1&amp;min=1&amp;amp;max=9"&gt;les 2 étoiles&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Bon jeu et bonne chance !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5168890059244723528?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5168890059244723528/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5168890059244723528' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5168890059244723528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5168890059244723528'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/comment-gagner-leuromillion.html' title='Comment gagner à l&apos;Euromillion'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-6208156858909308488</id><published>2006-09-15T08:03:00.000+02:00</published><updated>2006-11-22T09:21:41.266+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>Réflexion sur le comportement des gens sur la route</title><content type='html'>Un accident sur l'autoroute provoque deux bouchons. C'est du moins l'expérience que j'ai vécu hier en rentrant du travail.&lt;br /&gt;&lt;br /&gt;Oui j'ai bien dit deux bouchons, un naturellement du côté où la circulation est perturbée, mais c'est là que la problématique se pose, il provoque aussi un bouchon en sens inverse...&lt;br /&gt;&lt;br /&gt;La raison en est aussi simple que malheureuse, c'est que les gens, dans leur immense indélicatesse, freinent pour regarder ce qu'il s'est passé (en l'occurrence une voiture carbonisée sur le toit, vu qu'on roulait au pas j'ai aussi tourné la tête), et pour se dire :&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Oh il n'a pas de chance celui-là, mais il devait certainement mal conduire, ce qui n'est pas mon cas.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Mais ils ne se sont pas rendu compte que ceux de derrière ont dû planter sur les freins afin de ne pas les emboutir, et qu'en l'état de surcharge de trafic actuel, le moindre ralentissement peut devenir un danger redoutable.&lt;br /&gt;&lt;br /&gt;Mais tout ce complique quand d'autres personnes, encore moins intéressés par le malheureux sort de conducteur de la voiture accidentée et ses éventuels passagers, commence à dépasser par la droit. Et je ne ferai aucun commentaire sur les voitures, de taille inversement proportionnelle à leur capacités sociales, dans lesquelles ces gens roulent.&lt;br /&gt;&lt;br /&gt;En l'espace de quelques secondes, c'est donc un tableau tout à fait représentatif de notre société qui s'est peint de lui-même sur une autoroute...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-6208156858909308488?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/6208156858909308488/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=6208156858909308488' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6208156858909308488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/6208156858909308488'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/rflexion-sur-le-comportement-des-gens.html' title='Réflexion sur le comportement des gens sur la route'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-4966607292695277617</id><published>2006-09-14T07:58:00.000+02:00</published><updated>2006-12-19T12:19:19.961+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Envoyer un mail pour créer automatiquement un message</title><content type='html'>Voilà une petite fonction intégrée au sein du site qui va faire au moins un heureux. Car mes idées de billets surviennent forcément à des moments où je n'ai pas de connexion internet. Et comme il est impossible de rédiger un billet hors-ligne avec blogger (Quelqu'un me souffle que des plugins ont été fait pour palier à ce problème), l'envoie de mails est pour moi une facilité appréciée.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-4966607292695277617?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/4966607292695277617/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=4966607292695277617' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4966607292695277617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/4966607292695277617'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/envoyer-un-mail-pour-crer.html' title='Envoyer un mail pour créer automatiquement un message'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-3524474450984470217</id><published>2006-09-14T07:54:00.000+02:00</published><updated>2006-11-22T09:23:25.811+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Pourquoi un blog sur blogger.com et pas sur noisette.ch ?</title><content type='html'>La question est simple : avec tous les moyens que j'ai à disposition pour héberger mon propre blog, pourquoi est-ce que je l'héberge sur blogger.com ?&lt;br /&gt;&lt;br /&gt;La réponse ne l'est certes un peu moins, mais voici quelques points important de ma décision :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;L'indexation du blog est plus rapide et meilleure sur blogger.com, et donc mon &lt;a href="http://www.noisette.ch"&gt;Wiki de 2 noisettes&lt;/a&gt; en bénéficiera des retombées&lt;/li&gt;&lt;li&gt;La manipulation des données, notamment des dates est impossible sur blogger.com, les articles ici postés témoignent d'une plus grande crédibilité&lt;/li&gt;&lt;li&gt;La curiosité de tester ce qui pousse autant de personne de se tourner vers blogger.com&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;J'espère simplement que ce choix nous (les lecteurs de mes tickets intéressants et moi-même) sera effectivement profitable, et dans le cas contraire un remaniement de mon blog est toujours possible.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-3524474450984470217?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/3524474450984470217/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=3524474450984470217' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3524474450984470217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/3524474450984470217'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/pourquoi-un-blog-sur-bloggercom-et-pas.html' title='Pourquoi un blog sur blogger.com et pas sur noisette.ch ?'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2859534091932856215</id><published>2006-09-14T07:51:00.000+02:00</published><updated>2006-11-22T09:22:02.826+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Après le pull, le blog</title><content type='html'>Ca fait maintenant plus d'une année que j'ai acheté un pull blogger.com, alors je fête ça en me créant un vrai blog. Ca risque de déplaire à ma maman qui n'est pas pour ce genre de pratique, mais quand je lui aurai démontré le bienfondé des blogs, peut-être approuvera-t-elle au moins celui-ci...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2859534091932856215?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2859534091932856215/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2859534091932856215' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2859534091932856215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2859534091932856215'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/aprs-le-pull-le-blog.html' title='Après le pull, le blog'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-1775299835719014186</id><published>2006-06-06T07:55:00.000+02:00</published><updated>2006-11-22T09:22:11.580+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>L'union fait la force</title><content type='html'>&lt;span style="font-style: italic;"&gt;Initialement posté sur &lt;a href="http://www.noisette.ch/"&gt;Noisette.ch&lt;/a&gt; par KillerWhile &lt;/span&gt;&lt;span style="font-style: italic;"&gt;le 05.06.2005&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Si on en croit le sens commun, plus on est de personne pour tirer à une corde, plus on tire fort sur la corde.&lt;br /&gt;&lt;br /&gt;Cette constatation est vrai dans le sens ou si une personne tire sur une corde et lève 120 kilos, deux personnes n'auront aucun problème à lever plus.&lt;br /&gt;&lt;br /&gt;Là où le dicton atteint ces limites, c'est quand on prédit que si une personne lève 120 kilos, 2 personnes en lèvent 240 kilos, 3 personnes 360 kilos, et ainsi de suite.&lt;br /&gt;&lt;br /&gt;Un expérience menée initialement par Ringelmann en 1913 puis par Ingham et al. en 1974 montrent qu'une personne en groupe lève 20% de moins que seul.&lt;br /&gt;&lt;br /&gt;En résumé, 2 personnes soulèvent plus qu'une, mais proportionnellement, un personne soulève plus que 2.&lt;br /&gt;&lt;br /&gt;(Mon colloque (the economist) me souffle que ça s'appelle un rendement décroissant. En psychologie sociale, on parle de paresse sociale...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-1775299835719014186?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/1775299835719014186/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=1775299835719014186' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1775299835719014186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1775299835719014186'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/lunion-fait-la-force.html' title='L&apos;union fait la force'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-952655093073588324</id><published>2006-04-25T08:07:00.000+02:00</published><updated>2006-12-19T12:19:24.164+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>404 SEF, un mode Mambo génial ... en apparence</title><content type='html'>&lt;span style="font-style: italic;"&gt;Initialement posté sur &lt;/span&gt;&lt;a style="font-style: italic;" href="http://www.noisette.ch"&gt;Noisette.ch&lt;/a&gt;&lt;span style="font-style: italic;"&gt; par KillerWhile le 29.04.2006&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;404 SEF&lt;/span&gt; est un composant de Mambo/Joomla qui a pour but de permettre de disposer d'adresses amicales (userfriendly) pour afficher les pages. Sur le papier, c'est vraiment super utile car ça permet une bonne indexation auprès des moteurs de recherche. En pratique, c'est un calvaire pour les administrateurs des serveurs sur lesquelles tourne ce composant.&lt;br /&gt;&lt;br /&gt;Explication : un page &lt;span style="font-style: italic;"&gt;www.domaine.com/news/ma_premiere_news.html&lt;/span&gt; va devoir faire une requête dans la base de données pour savoir vers quelle url réelle &lt;span style="font-style: italic;"&gt;news/ma_premiere_news.html&lt;/span&gt; pointe. Ca signifie une requête du style&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SELECT realurl from jos_redirection WHERE fakeurl = 'news/ma_premiere_news.html'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Cette requête, qui recherche donc une valeur dans un champs VARCHAR et donc ne peut pas utiliser d'index, est vraiment sous-optimale et devient un syphon en terme de ressources sql.&lt;br /&gt;&lt;br /&gt;Une chose à faire donc : changer de composant de réécriture d'url (je n'en ai malheureusement pas encore de nouveau à proposer) ou s'en passer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-952655093073588324?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/952655093073588324/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=952655093073588324' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/952655093073588324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/952655093073588324'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/404-sef-un-mode-mambo-gnial-en.html' title='404 SEF, un mode Mambo génial ... en apparence'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-2162066759865267759</id><published>2006-01-20T08:07:00.000+01:00</published><updated>2006-11-22T09:24:37.245+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='thinking'/><title type='text'>Diffusion pour du pognon</title><content type='html'>&lt;span style="font-style: italic;"&gt;Initialement posté sur &lt;a href="http://www.noisette.ch/"&gt;Noisette.ch&lt;/a&gt; par KillerWhile le 19.01.2006&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Sous ce terme quelque peu familier je cherche à informer et mettre en garde les internautes contre les '''ventes pyramidales'''.&lt;br /&gt;&lt;br /&gt;Cette pratique a trouvé comme nouveau filon de diffusion les réseaux peer-to-peer, par lequel une grande masse de personne peut être rapidement touchée. Ainsi de nombreux fichiers contiennent des messages publicitaire évocateur qui promettent de gagner beaucoup en ne faisant pas grand chose.&lt;br /&gt;&lt;br /&gt;Cette pratique, pratiquée depuis le siècle passé avec les célèbres chaines de lettre, en plus d'être illégale en vertu des lois sur le commerce, n'est jamais gagnante pour l'utilisateur final.&lt;br /&gt;&lt;br /&gt;Le problème (ou l'avantage, ça dépend d'où on se place) de ce concept, c'est qu'il est très simple d'en comprendre le principe, qui théoriquement fonctionne à merveille (Si on doit versé 1€ à 6 personnes, puis se placer en 6ème position, qu'on envoie cette liste à 10 personnes qui eux l'enverrons à 10 autres, on gagne 10€ au premier niveau, puis 100€, puis 1000€, etc jusqu'au 6ème niveau ou vous toucheriez 1'000'000€. Alléchant, non), mais qu'il est plus dur d'en percevoir les limitations.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Il y a un nombre limité de participants potentiel (le 1'000'000 de personne qui vous donne 1€ va vouloir à son tour touver 1'000'000 de personnes chacune, ce qui nous fait 1'000'000'000'000 (il faudrait donc 1'000 milliards de personnes, sachant que la terre en compte 7, il faut trouver 993 milliards d'extra-terrestres). Donc tôt ou tard (mais plutôt tôt que tard), il n'y aura plus suffisamment de monde pour participer à la chaine, qui s'arrêtera et toute la base de la pyramide n'aura pas reçu 1 seul €.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Tout l'argent que vous gagner, quelqu'un d'autre l'a perdu. Si vous gagner 1000€, 1000 personnes ont perdu 1€. Même si les montants des pertes ne sont pas importants, le montant total peut représenter de lourdes pertes économiquement parlant.&lt;/li&gt;&lt;/ul&gt;Référence sur Wikipedia (en anglais) :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Make_money_fast%20Make%20money%20fast"&gt;http://en.wikipedia.org/wiki/Make_money_fast Make money fast&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Pyramid_schemes%20Pyramid%20schemes"&gt; http://en.wikipedia.org/wiki/Pyramid_schemes Pyramid schemes&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Et une autre très bonne référence : &lt;a href="http://members.impulse.net/%7Ethebob/Pyramid.html"&gt;http://members.impulse.net/~thebob/Pyramid.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-2162066759865267759?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/2162066759865267759/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=2162066759865267759' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2162066759865267759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/2162066759865267759'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/diffusion-pour-du-pognon.html' title='Diffusion pour du pognon'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-1657276670998257044</id><published>2005-07-19T08:12:00.000+02:00</published><updated>2006-12-19T12:21:14.605+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>Fribot 2005</title><content type='html'>&lt;span style="font-style:italic;"&gt;Initialement posté sur &lt;a href="http://www.noisette.ch"&gt;Noisette.ch&lt;/a&gt; par KillerWhile le 18.07.2005&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.noisette.ch/wiki/images/Img_9666.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://www.noisette.ch/wiki/images/Img_9666.jpg" border="0" alt="" /&gt;&lt;/a&gt;Après 2 premières manches lamentables, on finit toute de même à la 3ème place en étant la seule équipe à faire tomber toutes les quilles en moins de 3 minutes. L'équipe, composée de Christoph Walker, Sébastien Perroud (mon grand frère) et Thierry Gachet à la mécanique, et de Marius Erni et moi à la programmation gagne aussi le prix du meilleur code, en utilisant toutes les techniques possibles avec l'API Lejos sur le microprocesseur RCX. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.noisette.ch/wiki/images/Img_9529.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px;" src="http://www.noisette.ch/wiki/images/Img_9529.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;Fribot est un concours de robot sur une journée, où le but est de construire et programmer un robot lego Mindstorm pour qu'il accomplisse une tâche présentée le matin même. &lt;br /&gt;Le but cette année avait un petit gout de Eurobot, car on travaillait sur le même plateau de jeu. Il fallait mettre 2 ballons de rugby dans un trou, traverser un pont et descendre de quilles de l'autre côté. Le tout en un temps maximum de 3 minutes. &lt;br /&gt; &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.noisette.ch/wiki/images/Img_9617.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://www.noisette.ch/wiki/images/Img_9617.jpg" border="0" alt="" /&gt;&lt;/a&gt;Marius et Benoit Après une première phase de réflexion, Marius et moi attaquons le code. On divise le jeu en 3 parties : une partie pour pousser les balles de rugby, une autre pour traverser le pont, et la dernière pour descendre les quilles et ne pas quitter le plateau de jeu. &lt;br /&gt;Nos 2 premières manches ont été catastrophiques : une balle de poussée à la première, et rien du tout à la deuxième... On décide alors de réimplémenter tout le code avec des Behavior et un Arbitrator. La technique s'avère payante, d'une part parce que le robot n'a plus du tout un comportement aléatoire, mais d'autre part il nous permet de descendre 10 quilles lors de la 3ème manche, et nous permet d'accéder à la petite finale, ou on a simplement cartonné en faisant tomber une balle de rugby et les 16 quilles ! &lt;br /&gt; &lt;br /&gt;Et nous procure une joie non dissimulée, ainsi que le prix du meilleur code. &lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.noisette.ch/wiki/images/Img_9618.jpg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px;" src="http://www.noisette.ch/wiki/images/Img_9618.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-1657276670998257044?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1657276670998257044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/1657276670998257044'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2005/07/fribot-2005.html' title='Fribot 2005'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author></entry><entry><id>tag:blogger.com,1999:blog-5001452664427688683.post-5199856373833097137</id><published>2004-08-24T08:04:00.000+02:00</published><updated>2006-12-19T12:20:04.837+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='network'/><title type='text'>Gagner de l'argent grâce aux botnets</title><content type='html'>&lt;span style="font-style: italic;"&gt;Initialement posté sur &lt;a href="http://www.noisette.ch"&gt;Noisette.ch&lt;/a&gt; par KillerWhile le 23.08.2004&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Définition&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Les botnets sont des réseaux d'ordinateurs reliés à internet, sur lesquels ont été installés des logiciels à l'insu de leurs propriétaires. Ces zombies réagissent à des instructions précisent, permettant principalement de paralyser des sites par des attaques pas déni de service ou de relayer des spams en grande quantitée.&lt;br /&gt;&lt;br /&gt;Voir aussi la définition d'un &lt;a href="http://fr.wikipedia.org/wiki/Botnet"&gt;Botnet&lt;/a&gt; sur Wikipedia.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Construction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A l'heure actuelle, entre les exploits publiques et les proof of concept, beaucoup d'exemple de codes existent sur internet à partir desquels on peut infecter des machines pour construire son botnet.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Rémunération&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Illégales&lt;/span&gt;&lt;br /&gt;Deux méthodes illégales sont actuellement utilisées pour tirer profit d'un botnet :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Le racket de site : on lance un dos sur un site et on arrête uniquement si le webmaster paie une rançon. C'est risqué mais en ciblant bien les victimes, ca peut rapporter gros. &lt;/li&gt;&lt;li&gt;La revente de services à d'autres tiers. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Légales !&lt;/span&gt;&lt;br /&gt;D'autres techniques sont un peu plus légales, mais je ne m'y aventurerais quand même pas :&lt;br /&gt;Utiliser son botnet pour augmenter le trafic (raisonnablement) sur un site web, et générer par la même occasion des cliques sur des publicités présentes sur le site.&lt;br /&gt;Bien que cette technique puisse aussi être utilisée pour faire payer cher un annonceur, une utilisation plus rationnelle permettrait de se générer de gros revenus (de l'ordre du millier d'euro par mois).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;Résumé&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5001452664427688683-5199856373833097137?l=benoitperroud.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://benoitperroud.blogspot.com/feeds/5199856373833097137/comments/default' title='Publier les commentaires'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5001452664427688683&amp;postID=5199856373833097137' title='0 commentaires'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5199856373833097137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5001452664427688683/posts/default/5199856373833097137'/><link rel='alternate' type='text/html' href='http://benoitperroud.blogspot.com/2006/09/gagner-de-largent-grce-aux-botnets.html' title='Gagner de l&apos;argent grâce aux botnets'/><author><name>KillerWhile</name><uri>http://www.blogger.com/profile/17113505481300913194</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://www.noisette.ch/wiki/images/Raquette18.jpg'/></author><thr:total>0</thr:total></entry></feed>
