<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Alice, Bob and Mallory: Category Ruby</title>
    <link>http://alicebobandmallory.blogdns.com/articles/category/ruby</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>security and obscurity</description>
    <item>
      <title>Comparing instance variables in Ruby</title>
      <description>&lt;p&gt;Say you have two objects of the same class and you want to know what differs between them. Well actually you just want to know the instance variables in object &lt;em&gt;&lt;strong&gt;b&lt;/strong&gt;&lt;/em&gt; that differs from the ones in object &lt;em&gt;&lt;strong&gt;a&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To begin with, we need a class. I like cheese.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#080;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#B06;font-weight:bold"&gt;Cheese&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  attr_accessor &lt;span style="color:#A60"&gt;:name&lt;/span&gt;, &lt;span style="color:#A60"&gt;:weight&lt;/span&gt;, &lt;span style="color:#A60"&gt;:expire_date&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#06B;font-weight:bold"&gt;initialize&lt;/span&gt;(name, weight, expire_date)&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#33B"&gt;@name&lt;/span&gt;, &lt;span style="color:#33B"&gt;@weight&lt;/span&gt;, &lt;span style="color:#33B"&gt;@expire_date&lt;/span&gt; = name, weight, expire_date&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;Then we need some &lt;strike&gt;cheese&lt;/strike&gt; objects.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;stilton=&lt;span style="color:#036;font-weight:bold"&gt;Cheese&lt;/span&gt;.new(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;Stilton&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#00D;font-weight:bold"&gt;250&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;Date&lt;/span&gt;.parse(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;2009-11-02&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;))&lt;tt&gt;
&lt;/tt&gt;gorgonzola=&lt;span style="color:#036;font-weight:bold"&gt;Cheese&lt;/span&gt;.new(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;Gorgonzola&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#00D;font-weight:bold"&gt;250&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;Date&lt;/span&gt;.parse(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;2009-11-17&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;))&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;With only &lt;em&gt;name&lt;/em&gt;, &lt;em&gt;weight&lt;/em&gt; and an &lt;em&gt;expiration date&lt;/em&gt; it would be easy to compare those but imagine that these two objects has 42 properties. It does not stop there, you are being asked to compare 24 different classes in this way. Are you cringing yet?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Object#instance_variables&lt;/code&gt; to the rescue! Well, that and a small hack by me. Below I add a new method called &lt;code&gt;instance_variables_compare&lt;/code&gt; to &lt;code&gt;Object&lt;/code&gt;. The long method name is because I wanted to follow the naming already in place. Usually I prefer to do these kind of things as a &lt;code&gt;module&lt;/code&gt; and then &lt;code&gt;include&lt;/code&gt; them where appropriate but in this case I find that a &lt;a href="http://en.wikipedia.org/wiki/Monkey_patch"&gt;monkey patch&lt;/a&gt; will do.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#080;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#B06;font-weight:bold"&gt;Object&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#06B;font-weight:bold"&gt;instance_variables_compare&lt;/span&gt;(o)&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#036;font-weight:bold"&gt;Hash&lt;/span&gt;[*&lt;span style="color:#038;font-weight:bold"&gt;self&lt;/span&gt;.instance_variables.map {|v|&lt;tt&gt;
&lt;/tt&gt;      &lt;span style="color:#038;font-weight:bold"&gt;self&lt;/span&gt;.instance_variable_get(v)!=o.instance_variable_get(v) ? &lt;tt&gt;
&lt;/tt&gt;      [v,o.instance_variable_get(v)] : []}.flatten]&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;It returns the instance variables that differs as a &lt;a href="http://ruby-doc.org/core/classes/Hash.html"&gt;hash&lt;/a&gt; because it's handy and because I like it that way.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;gt;&amp;gt; stilton.instance_variables_compare(gorgonzola)&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; {&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;@name&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;Gorgonzola&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;@expire_date&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span style="color:#666"&gt;#&amp;lt;Date: 4910305/2,0,2299161&amp;gt;}&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; gorgonzola.instance_variables_compare(stilton)&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; {&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;@name&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;Stilton&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;@expire_date&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span style="color:#666"&gt;#&amp;lt;Date: 4910275/2,0,2299161&amp;gt;}&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; stilton.expire_date=gorgonzola.expire_date&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; &lt;span style="color:#666"&gt;#&amp;lt;Date: 4910305/2,0,2299161&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; stilton.instance_variables_compare(gorgonzola)&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; {&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;@name&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;=&amp;gt;&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;Gorgonzola&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;}&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; stilton.instance_variables_compare(stilton)&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; {}&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;If you ever think of using this code you should be aware of two things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This code is very untested and comes with no guarantees.&lt;/li&gt;
&lt;li&gt;Since instance variables &lt;strong&gt;spring into life the first time they are assigned to&lt;/strong&gt; you either have to work with objects that always initialize everything or you have to change &lt;code&gt;instance_variables_compare&lt;/code&gt; to handle this.&lt;/li&gt;
&lt;/ol&gt;</description>
      <pubDate>Mon, 02 Nov 2009 22:50:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:655f1e0f-877a-4696-8057-8efd315ed457</guid>
      <author>Jonas Elfström</author>
      <link>http://alicebobandmallory.blogdns.com/articles/2009/11/02/comparing-instance-variables-in-ruby</link>
      <category>Ruby</category>
    </item>
    <item>
      <title>Infinite ranges in C#</title>
      <description>&lt;p&gt;I &lt;a href="http://blogs.msdn.com/ericlippert/archive/2009/10/15/as-timeless-as-infinity.aspx"&gt;recently learned&lt;/a&gt; that C# is compliant with the &lt;a href="http://en.wikipedia.org/wiki/IEEE_754-1985"&gt;IEEE 754-1985&lt;/a&gt; for floating point arithmetics. That wasn't a big surprise but that &lt;a href="http://en.wikipedia.org/wiki/Division_by_zero#In_computer_arithmetic"&gt;division by zero&lt;/a&gt; is defined as &lt;code&gt;Infinity&lt;/code&gt; in it was! It actually kind of bothers me that I didn't know this.&lt;/p&gt;

&lt;p&gt;In mathematics division by zero is &lt;a href="http://en.wikipedia.org/wiki/Defined_and_undefined"&gt;undefined&lt;/a&gt; for real numbers but I guess &lt;code&gt;Infinity&lt;/code&gt; is a more pragmatic result. Or as a friend put it &lt;em&gt;"IEEE stands for Institute of Electrical and Electronics Engineers not Institute of Mathematics"&lt;/em&gt;&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;double&lt;/span&gt; n = &lt;span style="color:#60E;font-weight:bold"&gt;1&lt;/span&gt;&lt;span style="color:#60E;font-weight:bold"&gt;.0&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;n = n / &lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (n &amp;gt; &lt;span style="color:#00D;font-weight:bold"&gt;636413622384679305&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  System.Console.WriteLine(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;Yes it certainly is!&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;This C# code does not throw an exception, it simply leaves n defined as Infinity and a line written to the console.&lt;/p&gt;

&lt;p&gt;Ruby is &lt;a href="http://weblog.jamisbuck.org/2007/2/7/infinity"&gt;also&lt;/a&gt; IEEE 754-1985 compliant. It even lets you define &lt;a href="http://banisterfiend.wordpress.com/2009/10/02/wtf-infinite-ranges-in-ruby/"&gt;infinite ranges&lt;/a&gt;.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#036;font-weight:bold"&gt;Infinity&lt;/span&gt;=&lt;span style="color:#60E;font-weight:bold"&gt;1.0&lt;/span&gt;/&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;=&amp;gt;&lt;span style="color:#036;font-weight:bold"&gt;Infinity&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;(&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;..&lt;span style="color:#036;font-weight:bold"&gt;Infinity&lt;/span&gt;).include?(&lt;span style="color:#00D;font-weight:bold"&gt;162259276829213363391578010288127&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; &lt;span style="color:#038;font-weight:bold"&gt;true&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;(&lt;span style="color:#00D;font-weight:bold"&gt;7&lt;/span&gt;..&lt;span style="color:#036;font-weight:bold"&gt;Infinity&lt;/span&gt;).step(&lt;span style="color:#00D;font-weight:bold"&gt;7&lt;/span&gt;).take(&lt;span style="color:#00D;font-weight:bold"&gt;3&lt;/span&gt;).inject(&amp;amp;&lt;span style="color:#A60"&gt;:+&lt;/span&gt;) &lt;span style="color:#666"&gt;# 7+14+21&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; &lt;span style="color:#00D;font-weight:bold"&gt;42&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;I can't say I see very much &lt;a href="http://www.michaelharrison.ws/weblog/?p=163"&gt;use&lt;/a&gt; of this but it brings a kind of completeness to the handling of infinities. Unfortunately it seems we don't get that in C# out of the box because &lt;code&gt;Enumerable.Range&lt;/code&gt; takes &lt;code&gt;&amp;lt;int&amp;gt;,&amp;lt;int&amp;gt;&lt;/code&gt; as parameters and there's no &lt;code&gt;Infinity&lt;/code&gt; definition for &lt;code&gt;int&lt;/code&gt;.  That's unless someone wrote a generic Range class. Turns out &lt;a href="http://stackoverflow.com/users/22656/jon-skeet"&gt;none other&lt;/a&gt; than &lt;a href="http://www.yoda.arachsys.com/csharp/"&gt;Jon Skeet&lt;/a&gt; did in his &lt;a href="http://www.yoda.arachsys.com/csharp/miscutil/"&gt;MiscUtil&lt;/a&gt;. Dowload MiscUtil and then by &lt;code&gt;using MiscUtil.Collections;&lt;/code&gt; you can:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;double&lt;/span&gt; n = &lt;span style="color:#60E;font-weight:bold"&gt;1&lt;/span&gt;&lt;span style="color:#60E;font-weight:bold"&gt;.0&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; infinity = n / &lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; r = new Range&amp;lt;&lt;span style="color:#339;font-weight:bold"&gt;double&lt;/span&gt;&amp;gt;(&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;, infinity);&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; (r.Contains(&lt;span style="color:#00D;font-weight:bold"&gt;4711&lt;/span&gt;))&lt;tt&gt;
&lt;/tt&gt;  System.Console.WriteLine(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;Yes it certainly does!&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; sum = r.Step(&lt;span style="color:#60E;font-weight:bold"&gt;7&lt;/span&gt;&lt;span style="color:#60E;font-weight:bold"&gt;.0&lt;/span&gt;).Take(&lt;span style="color:#00D;font-weight:bold"&gt;3&lt;/span&gt;).Sum();&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;And guess what, it works like a charm! &lt;code&gt;4711&lt;/code&gt; is part of positive infinity and &lt;code&gt;sum&lt;/code&gt; is 42.0 and all is good.&lt;/p&gt;

&lt;p&gt;&lt;font style="color:red;font-weight:bold"&gt;Edit&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;There's also a couple of predefined constants. Thanks to Eric for pointing that out.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; r = new Range&amp;lt;&lt;span style="color:#339;font-weight:bold"&gt;double&lt;/span&gt;&amp;gt;(&lt;span style="color:#00D;font-weight:bold"&gt;7&lt;/span&gt;,  System.Double.PositiveInfinity);&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; sum = r.Step(&lt;span style="color:#60E;font-weight:bold"&gt;7&lt;/span&gt;&lt;span style="color:#60E;font-weight:bold"&gt;.0&lt;/span&gt;).Take(&lt;span style="color:#00D;font-weight:bold"&gt;3&lt;/span&gt;).Sum();&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;</description>
      <pubDate>Tue, 20 Oct 2009 20:41:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:1337fd12-5058-4b35-bbf4-c9d0c4e9ade8</guid>
      <author>Jonas Elfström</author>
      <link>http://alicebobandmallory.blogdns.com/articles/2009/10/20/infinite-ranges-in-c</link>
      <category>Ruby</category>
      <category>C#</category>
      <category>Math</category>
    </item>
    <item>
      <title>The Thrush combinator in C#</title>
      <description>&lt;p&gt;Last year I read &lt;a href="http://github.com/raganwald/homoiconic/blob/master/README.markdown"&gt;Reg "Raganwald'" Braithwaite's&lt;/a&gt; excellent post &lt;a href="http://github.com/raganwald/homoiconic/blob/master/2008-10-30/thrush.markdown#readme"&gt;The Thrush&lt;/a&gt; and he  explains it as &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;The thrush is written Txy = yx. It reverses evaluation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Back then I didn't even consider trying to implement it in C#. That was before I digged deeper into &lt;a href="http://msdn.microsoft.com/en-us/library/bb397687.aspx"&gt;lambda expressions&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"&gt;extension methods&lt;/a&gt; in C# 3.0 and way before last night when I read Debasish Ghosh's post on how to &lt;a href="http://debasishg.blogspot.com/2009/09/thrush-combinator-in-scala.html"&gt;implement the Thrush in Scala&lt;/a&gt;. After reading that my first thought was if it was possible to do the same in C#. Here's my attempt.&lt;/p&gt;

&lt;p&gt;At first I struggled with the static typing and headed for an easy way out using Object in the extension method of Object:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;public &lt;span style="color:#080;font-weight:bold"&gt;static&lt;/span&gt; object Into(this Object obj, Func&amp;lt;object, object&amp;gt; f)&lt;tt&gt;
&lt;/tt&gt;{  &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; f.Invoke(obj); }&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;My goal was to translate the Ruby example&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;(&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;..&lt;span style="color:#00D;font-weight:bold"&gt;100&lt;/span&gt;).select(&amp;amp;&lt;span style="color:#A60"&gt;:odd?&lt;/span&gt;).inject(&amp;amp;&lt;span style="color:#A60"&gt;:+&lt;/span&gt;).into { |x| x * x }&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;in Raganwald's post to C#.&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;Which reads "Take the numbers from 1 to 100, keep the odd ones, take the sum of those, and then answer the square of that number."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But with the Object based extension method I had to do some ugly casts.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; r = Enumerable.Range(&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;, &lt;span style="color:#00D;font-weight:bold"&gt;100&lt;/span&gt;).Where(x =&amp;gt; Odd(x)).Sum().Into(x =&amp;gt; (&lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt;)x * (&lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt;)x);&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;With som added typing I could do: &lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; result = Enumerable.Range(&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;, &lt;span style="color:#00D;font-weight:bold"&gt;100&lt;/span&gt;).Where(x =&amp;gt; Odd(x)).Sum().Into(x =&amp;gt; x * x);&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;But that merely moved the cast to the ext. method and also made it work for integers only.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;public &lt;span style="color:#080;font-weight:bold"&gt;static&lt;/span&gt; &lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt; Into(this Object obj, Func&amp;lt;&lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt;, &lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt;&amp;gt; f)&lt;tt&gt;
&lt;/tt&gt;{ &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; f.Invoke((&lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt;)obj); }&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;Then I remembered generics and method type inference.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;public &lt;span style="color:#080;font-weight:bold"&gt;static&lt;/span&gt; T Into&amp;lt;T&amp;gt;(this T obj, Func&amp;lt;T, T&amp;gt; f)&lt;tt&gt;
&lt;/tt&gt;{ &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; f(obj); }&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;And now not only the casts were gone but I also got a thrush combinator almost as flexible as the one in Ruby.&lt;/p&gt;

&lt;p&gt;Contrived example follows:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; test = &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;ball&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; ball = test.Into(s =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;Are we having a &lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; + s + &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt; yet?&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt; &lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;The odd part&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;Odd(x)&lt;/em&gt; method call in the calculation above is a plain static method.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;private &lt;span style="color:#080;font-weight:bold"&gt;static&lt;/span&gt; &lt;span style="color:#339;font-weight:bold"&gt;bool&lt;/span&gt; Odd(&lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt; n)&lt;tt&gt;
&lt;/tt&gt;{ &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; (n % &lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt; != &lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;); }&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;If you want an even more terse syntax you could try an ext. method on IEnumerable like this:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;public &lt;span style="color:#080;font-weight:bold"&gt;static&lt;/span&gt; IEnumerable&amp;lt;&lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt;&amp;gt; Odd(this IEnumerable&amp;lt;&lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt;&amp;gt; en)&lt;tt&gt;
&lt;/tt&gt;{ &lt;span style="color:#080;font-weight:bold"&gt;return&lt;/span&gt; en.Where(n =&amp;gt; n % &lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt; != &lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;); }&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Gives:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;var&lt;/span&gt; result = Enumerable.Range(&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;, &lt;span style="color:#00D;font-weight:bold"&gt;100&lt;/span&gt;).Odd().Sum().Into(x =&amp;gt; x * x);&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;Also as a general alternative to &lt;code&gt;.Sum()&lt;/code&gt; I could have used &lt;code&gt;.Aggregate((x, y) =&amp;gt; x + y))&lt;/code&gt; but I found it a bit verbose.&lt;/p&gt;

&lt;p&gt;In C# I don't think it's possible to pull off the Symbol#to_proc stuff that Ruby does. That's the &lt;em&gt;&amp;amp;:&lt;/em&gt; in the &lt;em&gt;select(&amp;amp;:odd?)&lt;/em&gt; and the &lt;em&gt;inject(&amp;amp;:+)&lt;/em&gt; in the Ruby example. Raganwald has a great &lt;a href="http://weblog.raganwald.com/2007/11/fun-with-symboltoproc.html"&gt;post&lt;/a&gt; on that too.&lt;/p&gt;

&lt;p&gt;&lt;font style="color:red;font-weight:bold"&gt;Edit&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="http://stackoverflow.com/questions/1528319/operators-as-method-parameters-in-c-and-the-thrush-combinator"&gt;Jon Skeet's nice answer&lt;/a&gt; on StackOverflow to my question on how to make this even more Ruby-like. I have to try out that Operator class later though.&lt;/p&gt;

&lt;p&gt;&lt;font style="color:red;font-weight:bold"&gt;Edit 2009-10-07&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;One thing I found a bit surprising is that by implementing the Into ext. method in this way it not only works for all objects based on &lt;code&gt;System.Object&lt;/code&gt; but it also works  for &lt;a href="http://msdn.microsoft.com/en-us/library/s1ax56ch.aspx"&gt;value types&lt;/a&gt;.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt; n=&lt;span style="color:#00D;font-weight:bold"&gt;4711&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#339;font-weight:bold"&gt;int&lt;/span&gt; oddOrZero = n.Into(x =&amp;gt; x % &lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt; !=&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt; ? x : &lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;); &lt;span style="color:#666"&gt;// 4711&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;n = &lt;span style="color:#00D;font-weight:bold"&gt;4712&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;oddOrZero = n.Into(x =&amp;gt; x % &lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt; != &lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt; ? x : &lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;); &lt;span style="color:#666"&gt;// 0&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;&lt;font style="color:red;font-weight:bold"&gt;Edit 2009-10-12&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;My confusion did stem from my lack of understanding of &lt;a href="http://msdn.microsoft.com/en-us/library/bb383977(loband).aspx"&gt;extension methods&lt;/a&gt;. Ex. methods are in fact not extending &lt;code&gt;System.Object&lt;/code&gt; or any other type, they are "&lt;a href="http://blogs.msdn.com/ericlippert/about.aspx"&gt;nothing more than a pleasant syntax for calling a static method&lt;/a&gt;" in  case no instance method with the same name can be found.&lt;/p&gt;</description>
      <pubDate>Tue, 06 Oct 2009 20:35:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:b02ff8f0-44fb-44ca-a309-eb0fd074a495</guid>
      <author>Jonas Elfström</author>
      <link>http://alicebobandmallory.blogdns.com/articles/2009/10/06/the-thrush-combinator-in-c</link>
      <category>Ruby</category>
      <category>C#</category>
    </item>
    <item>
      <title>A case for using only three different digits in keypad codes</title>
      <description>&lt;p&gt;Keypads have obvious security problems and keypads accepting a stream of digits with no # or enter in between, while checking for the four digit long code, are even worse.&lt;/p&gt;

&lt;p&gt;The important part is to not leak the digits in the code &lt;a href="http://www.schneier.com/blog/archives/2009/07/information_lea_1.html"&gt;by wear&lt;/a&gt; or intentional markings because if they leak it's suddenly very far from 10000 combinations.&lt;/p&gt;

&lt;p&gt;If the "lock picker" only knows that the code contains four digits there are 10000 combinations. Keypads accepting a stream of digits can then be opened in a maximum of 10003 keystrokes using the &lt;a href="http://en.wikipedia.org/wiki/De_Bruijn_sequence#Uses"&gt;De
Bruijn sequence&lt;/a&gt;. That is still quite a lot.&lt;/p&gt;

&lt;p&gt;Below is a Ruby implementation of the &lt;a href="http://www.hakank.org/comb/debruijn.cgi"&gt;De
Bruijn sequence&lt;/a&gt;.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#666"&gt;# De Bruijn sequence&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#666"&gt;# Original implementation by Frank Ruskey (1994)&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#666"&gt;# translated to C by Joe Sawada&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#666"&gt;# and further translated to Ruby by Jonas Elfström (2009)&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#33B"&gt;@n&lt;/span&gt;=&lt;span style="color:#00D;font-weight:bold"&gt;4&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#33B"&gt;@k&lt;/span&gt;=&lt;span style="color:#00D;font-weight:bold"&gt;10&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#33B"&gt;@a&lt;/span&gt;=[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#33B"&gt;@sequence&lt;/span&gt;=[]&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#06B;font-weight:bold"&gt;debruijn&lt;/span&gt;(t, p, alike)&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; t&amp;gt;&lt;span style="color:#33B"&gt;@n&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#33B"&gt;@n&lt;/span&gt;%p==&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;.upto(p) {|j| &lt;span style="color:#33B"&gt;@sequence&lt;/span&gt;&amp;lt;&amp;lt;&lt;span style="color:#33B"&gt;@a&lt;/span&gt;[j]}&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#33B"&gt;@a&lt;/span&gt;[t]=&lt;span style="color:#33B"&gt;@a&lt;/span&gt;[t-p]&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#33B"&gt;@a&lt;/span&gt;[t]&amp;gt;&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      debruijn(t+&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;,p,alike+&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      debruijn(t+&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;,p,alike)&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    (&lt;span style="color:#33B"&gt;@a&lt;/span&gt;[t-p]+&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;).upto(&lt;span style="color:#33B"&gt;@k&lt;/span&gt;-&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;) {|j|&lt;tt&gt;
&lt;/tt&gt;      &lt;span style="color:#33B"&gt;@a&lt;/span&gt;[t]=j&lt;tt&gt;
&lt;/tt&gt;      debruijn(t+&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;,t,alike+&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;debruijn(&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;,&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;,&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;print &lt;span style="color:#33B"&gt;@sequence&lt;/span&gt;.join&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;It's not uncommon to find keypads with 4 of the 10 keys worn down and if you do you can be pretty sure that the code contains those four different digits. The number of possible combinations are 4! = 4x3x2x1 = 24. I got curious to see if there's a kind of &lt;a href="http://mathworld.wolfram.com/deBruijnSequence.html"&gt;De Bruijn sequence&lt;/a&gt; for this that brings down the 4*24=96 keystrokes. By scribbling in a &lt;a href="http://www.scintilla.org/SciTE.html"&gt;text editor&lt;/a&gt; I quickly realized there's not a clean sequence. Not clean in the way that a sequence following the rules can be created. Also it's probably even quite daunting to present it as mathematically dense and beautiful as the &lt;a href="http://www.stefangeens.com/2004/10/the-de-bruijn-c.html"&gt;De Bruijn&lt;/a&gt; but that could be my less than great &lt;a href="http://en.wikipedia.org/wiki/Combinatorics"&gt;combinatorics&lt;/a&gt; speaking.&lt;/p&gt;

&lt;p&gt;I made a quick and dirty brute force hack to try to find a shorter sequence.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;seq=[]&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;.upto(&lt;span style="color:#00D;font-weight:bold"&gt;4&lt;/span&gt;) {|a| &lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;.upto(&lt;span style="color:#00D;font-weight:bold"&gt;4&lt;/span&gt;) {|b| &lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;.upto(&lt;span style="color:#00D;font-weight:bold"&gt;4&lt;/span&gt;) {|c| &lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;.upto(&lt;span style="color:#00D;font-weight:bold"&gt;4&lt;/span&gt;) {|d|&lt;tt&gt;
&lt;/tt&gt;  seq &amp;lt;&amp;lt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;%d%d%d%d&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; % [a,b,c,d] &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; !(a==b || a==c || a==d || b==c || b==d || c==d)&lt;tt&gt;
&lt;/tt&gt;}}}}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;s=seq[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;seq.delete_at(&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;while&lt;/span&gt; (seq.length&amp;gt;&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  next_code=(seq.select {|c| c[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;..&lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt;]==s[&lt;span style="color:#00D;font-weight:bold"&gt;-3&lt;/span&gt;..&lt;span style="color:#00D;font-weight:bold"&gt;-1&lt;/span&gt;]})&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; next_code.empty?&lt;tt&gt;
&lt;/tt&gt;    next_code=(seq.select {|c| c[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;..&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;]==s[&lt;span style="color:#00D;font-weight:bold"&gt;-2&lt;/span&gt;..&lt;span style="color:#00D;font-weight:bold"&gt;-1&lt;/span&gt;]})&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; next_code.empty? &lt;tt&gt;
&lt;/tt&gt;      next_code=(seq.select {|c| c[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;]==s[&lt;span style="color:#00D;font-weight:bold"&gt;-1&lt;/span&gt;]})&lt;tt&gt;
&lt;/tt&gt;      s+=next_code[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;][&lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;..&lt;span style="color:#00D;font-weight:bold"&gt;3&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;      seq.delete_at(seq.index(next_code[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;]))&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      s+=next_code[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;][&lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt;..&lt;span style="color:#00D;font-weight:bold"&gt;3&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;      seq.delete_at(seq.index(next_code[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;]))&lt;tt&gt;
&lt;/tt&gt;    &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    next_code=(seq.select {|c| c[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;..&lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt;]==s[&lt;span style="color:#00D;font-weight:bold"&gt;-3&lt;/span&gt;..&lt;span style="color:#00D;font-weight:bold"&gt;-1&lt;/span&gt;]})&lt;tt&gt;
&lt;/tt&gt;    s+=next_code[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;][&lt;span style="color:#00D;font-weight:bold"&gt;3&lt;/span&gt;].chr&lt;tt&gt;
&lt;/tt&gt;    seq.delete_at(seq.index(next_code[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;]))&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;The above code takes the first code "1234" of the 24 and then searches the rest of the array for a code beginning with "234". It finds "2341" and adds "1" to the end of &lt;em&gt;s&lt;/em&gt; and continues to look for "341" and so on. Relatively soon there is no three digit match and then it tries two digits and eventually even that fails and then it gets the first one digit match. The resulting sequence is: &lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;123412314231243121342132413214321&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From 96 to 33 keystrokes. Not as effective as De Bruijn but still significant. Unlike De Bruijn I have absolutely no proof that this is the shortest one possible but it seems likely. Also notice that in the middle of the sequence we find "3121" and "1213". Those break the criteria of four different digits but they seem to be necessary to be able to enter the reversed mode. Try reading the sequence forward and backwards to see what I mean.&lt;/p&gt;

&lt;p&gt;If the code only contains two digits it's gets even more trivial to try them all. There are 14 possible codes and by &lt;em&gt;compressing&lt;/em&gt; those to one sequence you get down to 20 keystrokes. &lt;/p&gt;

&lt;p&gt;Things get a little more interresting if three buttons are worn. It turns out that the repeated digits can be placed in the code in six different ways.&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;0012,1002,1200,0102,0120,1020&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's 6x2x3=36 combinations and, maybe a little unintuitive, 12 more than if you are using four different digits. I compressed it down to 49 key strokes. Unlike the sequence for four different digits I can't find it with google and I know it's kind of security by obscurity but that could give a tiny amount of extra trouble to an attacker. I will not be the first one publishing it.&lt;/p&gt;

&lt;p&gt;Be aware that if an attacker knows you are using a 0012-like code he gets a smaller space to search. 6x8x9x10=4320 instead of 10000. You have to weight the risk of button leaks against a code protocol leak.&lt;/p&gt;</description>
      <pubDate>Sun, 27 Sep 2009 21:02:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:9e10d05b-1a1d-46a1-82da-0ba366d32035</guid>
      <author>Jonas Elfström</author>
      <link>http://alicebobandmallory.blogdns.com/articles/2009/09/27/a-case-for-using-only-three-different-digits-in-keypad-codes</link>
      <category>Security</category>
      <category>Ruby</category>
    </item>
    <item>
      <title>Why you should use four different digits for keypad locks</title>
      <description>&lt;p&gt;I made a couple of very bad mistakes in this article so I took it down. Hopefully I'm more on track in the &lt;a href="http://alicebobandmallory.com/articles/2009/09/27/a-case-for-using-only-three-different-digits-in-keypad-codes"&gt;sequel&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 23 Sep 2009 19:49:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:327947c8-2f2d-4ca7-9ddf-bdd8b74cd9f4</guid>
      <author>Jonas Elfström</author>
      <link>http://alicebobandmallory.blogdns.com/articles/2009/09/23/why-you-should-use-four-different-digits-for-keypad-locks</link>
      <category>Security</category>
      <category>Ruby</category>
    </item>
    <item>
      <title>Breaking simple ciphers</title>
      <description>&lt;p&gt;The last few days I've happened to stumble over a couple of ciphers and I just couldn't help myself from trying to break them.&lt;/p&gt;

&lt;pre&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;The Lost Symbol&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dan Brown has a new book coming out and part of the promotion is this  cipher text "AOFACFSOA FSZWBEIC EIOA ZOHSFWQWOA OQQSDW". 
The WQW, QQ and three of the words ending with an A made me believe we could be dealing with a substitution cipher and maybe even a Caesar cipher, the most simple of them all.&lt;/p&gt;

&lt;p&gt;As usual my tool of choice was Ruby and in this case the splendid Interactive Ruby Shell.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;$&lt;/span&gt; irb&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; s=&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;AOFACFSOA FSZWBEIC EIOA ZOHSFWQWOA OQQSDW&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;AOFACFSOA FSZWBEIC EIOA ZOHSFWQWOA OQQSDW&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; &lt;span style="color:#080;font-weight:bold"&gt;def&lt;/span&gt; &lt;span style="color:#06B;font-weight:bold"&gt;caesar&lt;/span&gt;(text,n)&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt;   alphas=(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;A&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;..&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;Z&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;).to_a*&lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt;   text.tr(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;A-Z&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;, alphas[n..n+&lt;span style="color:#00D;font-weight:bold"&gt;26&lt;/span&gt;].join)&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; &lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;.upto(&lt;span style="color:#00D;font-weight:bold"&gt;25&lt;/span&gt;) &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt; |n| puts &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;%2d. %s&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; % [n, caesar(s,n)] &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;1&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;BPGBDGTPB&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;GTAXCFJD&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;FJPB&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;APITGXRXPB&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;PRRTEX&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;2&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;CQHCEHUQC&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;HUBYDGKE&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;GKQC&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;BQJUHYSYQC&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;QSSUFY&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;3&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;DRIDFIVRD&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;IVCZEHLF&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;HLRD&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;CRKVIZTZRD&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;RTTVGZ&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;4&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;ESJEGJWSE&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;JWDAFIMG&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;IMSE&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;DSLWJAUASE&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;SUUWHA&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;5&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;FTKFHKXTF&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;KXEBGJNH&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;JNTF&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ETMXKBVBTF&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;TVVXIB&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;6&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;GULGILYUG&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;LYFCHKOI&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;KOUG&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;FUNYLCWCUG&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;UWWYJC&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;7&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;HVMHJMZVH&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;MZGDILPJ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;LPVH&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;GVOZMDXDVH&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;VXXZKD&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;8&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;IWNIKNAWI&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;NAHEJMQK&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;MQWI&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;HWPANEYEWI&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;WYYALE&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#00D;font-weight:bold"&gt;9&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;JXOJLOBXJ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;OBIFKNRL&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;NRXJ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;IXQBOFZFXJ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;XZZBMF&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;10&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;KYPKMPCYK&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;PCJGLOSM&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;OSYK&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;JYRCPGAGYK&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;YAACNG&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;11&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;LZQLNQDZL&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;QDKHMPTN&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;PTZL&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;KZSDQHBHZL&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ZBBDOH&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;12&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;MARMOREAM&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;RELINQUO&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;QUAM&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;LATERICIAM&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ACCEPI&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;13&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;NBSNPSFBN&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;SFMJORVP&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;RVBN&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;MBUFSJDJBN&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;BDDFQJ&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;14&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;OCTOQTGCO&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;TGNKPSWQ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;SWCO&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;NCVGTKEKCO&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;CEEGRK&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;15&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;PDUPRUHDP&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;UHOLQTXR&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;TXDP&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ODWHULFLDP&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;DFFHSL&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;16&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;QEVQSVIEQ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;VIPMRUYS&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;UYEQ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;PEXIVMGMEQ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;EGGITM&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;17&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;RFWRTWJFR&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;WJQNSVZT&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;VZFR&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;QFYJWNHNFR&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;FHHJUN&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;18&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;SGXSUXKGS&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;XKROTWAU&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;WAGS&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;RGZKXOIOGS&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;GIIKVO&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;19&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;THYTVYLHT&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;YLSPUXBV&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;XBHT&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;SHALYPJPHT&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;HJJLWP&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;20&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;UIZUWZMIU&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ZMTQVYCW&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;YCIU&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;TIBMZQKQIU&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;IKKMXQ&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;21&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;VJAVXANJV&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ANURWZDX&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ZDJV&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;UJCNARLRJV&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;JLLNYR&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;22&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;WKBWYBOKW&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;BOVSXAEY&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;AEKW&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;VKDOBSMSKW&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;KMMOZS&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;23&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;XLCXZCPLX&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;CPWTYBFZ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;BFLX&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;WLEPCTNTLX&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;LNNPAT&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;24&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;YMDYADQMY&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;DQXUZCGA&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;CGMY&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;XMFQDUOUMY&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;MOOQBU&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;25&lt;/span&gt;. &lt;span style="color:#036;font-weight:bold"&gt;ZNEZBERNZ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;ERYVADHB&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;DHNZ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;YNGREVPVNZ&lt;/span&gt; &lt;span style="color:#036;font-weight:bold"&gt;NPPRCV&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;Take a closer look at row 12.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MARMOREAM RELINQUO QUAM LATERICIAM ACCEPI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I found Rome a city of bricks and left it a city of marble.&lt;/em&gt; - Google tells me it's Augustus.&lt;/p&gt;

&lt;p&gt;The code is not the most clear I've written but if you read Ruby in your sleep you can skip this part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;('A'..'Z')&lt;/strong&gt; is a range in Ruby. Another, maybe more obvious, example of a range is &lt;strong&gt;(0..7)&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.to_a&lt;/strong&gt; could be read as to_array and unsurprisingly it converts a range to an array. &lt;strong&gt;(0..7).to_a&lt;/strong&gt; will create  &lt;strong&gt;[0, 1, 2, 3, 4, 5, 6, 7]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The operator * for arrays appends n copies of the array. Thus &lt;strong&gt;[0,1,2]*2&lt;/strong&gt; will create  &lt;strong&gt;[0,1,2,0,1,2]&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ruby-doc.org/core/classes/String.html#M000845"&gt;String#tr&lt;/a&gt; works the same way as the Unix command tr, it translates the characters in the string according to the from and to parameters. &lt;/p&gt;

&lt;p&gt;At last &lt;strong&gt;.join&lt;/strong&gt; converts the array to a string.&lt;/p&gt;

&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;The recruiting agency&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A government agency responsible for signals intelligence is hiring. Among the qualifications they are looking for is the ability to break a certain cipher. I will not publish their cipher here but instead one of my own, constructed in the same way as theirs.&lt;pre&gt;"VGhpcyBpcyBleGNsdXNpdmUgZm9yIHlvdSwgb3I/IGMNR0d
LCkZPXgpTRV8K\nTENEQ1lCCkhfXgpoT1NFRElPCkNZCksKSE9eXk
9YCklYU1peRU1YS1pCT1gK\nXkJLRAp5SUJET0NPWAQ="&lt;/pre&gt;
At first glance it looked like Base64 and the ending "=" made it even more likely.&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#F00;background-color:#FAA"&gt;$&lt;/span&gt; irb&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; require &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;base64&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; cipher = &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;VGhpcyBpcyBleGNsdXNpdmUgZm9yIHlvdSwgb3I/IGMNR0dLCkZPXgpTRV8K&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;TENEQ1lCCkhfXgpoT1NFRElPCkNZCksKSE9eXk9YCklYU1peRU1YS1pCT1gK&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;XkJLRAp5SUJET0NPWAQ=&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; decoded=&lt;span style="color:#036;font-weight:bold"&gt;Base64&lt;/span&gt;.decode64(cipher)&lt;tt&gt;
&lt;/tt&gt;=&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;This is exclusive for you, or? c&lt;/span&gt;&lt;span style="color:#b0b"&gt;\r&lt;/span&gt;&lt;span style=""&gt;GGK&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;FO^&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;SE&lt;em&gt;&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;LCDCYB&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;H&lt;/em&gt;^&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;hOSEDIO&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;CY&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;K&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;HO^^OX&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;IXSZ^EMXKZBOX&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;^BKD&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style=""&gt;yIBDOCOX&lt;/span&gt;&lt;span style="color:#b0b"&gt;\004&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;

&lt;p&gt;So it's Base64 but to no surprise it didn't end there. The "This is exclusive for you, or?" hinted at XOR so I tried XORing the text with 0-255.&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;gt;&amp;gt; code=decoded[&lt;span style="color:#00D;font-weight:bold"&gt;31&lt;/span&gt;..decoded.length].split(&lt;span style="background-color:#fff0ff"&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; &lt;span style="color:#036;font-weight:bold"&gt;File&lt;/span&gt;.open(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;xor.txt&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;w&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;) { |file|&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;?&amp;gt;&lt;/span&gt;   &lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;.upto(&lt;span style="color:#00D;font-weight:bold"&gt;255&lt;/span&gt;) {|n|&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#00D;font-weight:bold"&gt;?&amp;gt;&lt;/span&gt;     file.write(n.to_s + &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt;     code.each {|c| file.write( (c[&lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;]^n).chr ) }&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt;     file.write(&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style="color:#b0b"&gt;\n&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt;   }&lt;tt&gt;
&lt;/tt&gt;&amp;gt;&amp;gt; }&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;A quick look in the file told me that XORing with 42 was the solution.&lt;/p&gt;

&lt;p&gt;Now you know how to break two of the most simple cipher methods. Use the knowledge wisely. :)&lt;/p&gt;</description>
      <pubDate>Wed, 16 Sep 2009 20:19:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:bfe9c11f-97c5-458b-a238-2304814e7794</guid>
      <author>Jonas Elfström</author>
      <link>http://alicebobandmallory.blogdns.com/articles/2009/09/16/breaking-simple-ciphers</link>
      <category>Ruby</category>
      <category>Cryptography</category>
    </item>
    <item>
      <title>Setting charset with a before filter in Sinatra</title>
      <description>&lt;p&gt;In the git example in my &lt;a href="/articles/2009/06/11/an-average-application-in-the-clouds"&gt;previous post&lt;/a&gt; about Sinatra and Heroku I happened to mention a filter for using UTF-8. I remember finding it somewhere on the net but I can't remember where and it seems my current google-fu is as weak as my memory. Anyway, it looks like this:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#036;font-weight:bold"&gt;CONTENT_TYPES&lt;/span&gt; = {&lt;span style="color:#A60"&gt;:html&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;text/html&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span style="color:#A60"&gt;:css&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;text/css&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;                &lt;span style="color:#A60"&gt;:js&lt;/span&gt;  =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;application/javascript&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;before &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; request_uri = &lt;span style="color:#080;font-weight:bold"&gt;case&lt;/span&gt; request.env[&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;REQUEST_URI&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;   &lt;span style="color:#080;font-weight:bold"&gt;when&lt;/span&gt; &lt;span style="background-color:#fff0ff"&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;span style="color:#04D"&gt;\.&lt;/span&gt;&lt;span style="color:#808"&gt;css$&lt;/span&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;/span&gt; : &lt;span style="color:#A60"&gt;:css&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;   &lt;span style="color:#080;font-weight:bold"&gt;when&lt;/span&gt; &lt;span style="background-color:#fff0ff"&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;span style="color:#04D"&gt;\.&lt;/span&gt;&lt;span style="color:#808"&gt;js$&lt;/span&gt;&lt;span style="color:#404"&gt;/&lt;/span&gt;&lt;/span&gt;  : &lt;span style="color:#A60"&gt;:js&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;   &lt;span style="color:#080;font-weight:bold"&gt;else&lt;/span&gt;          &lt;span style="color:#A60"&gt;:html&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; &lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt; content_type &lt;span style="color:#036;font-weight:bold"&gt;CONTENT_TYPES&lt;/span&gt;[request_uri], &lt;span style="color:#A60"&gt;:charset&lt;/span&gt; =&amp;gt; &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;utf-8&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;</description>
      <pubDate>Fri, 31 Jul 2009 08:30:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:0814199e-0299-481a-b0df-3fd5d2a7bb24</guid>
      <author>Jonas Elfström</author>
      <link>http://alicebobandmallory.blogdns.com/articles/2009/07/31/setting-charset-with-a-before-filter-in-sinatra</link>
      <category>Ruby</category>
    </item>
    <item>
      <title>An average application in the clouds</title>
      <description>&lt;p&gt;A couple of days ago I published my first applicaiton "in the cloud". I named it &lt;a href="http://average.heroku.com/"&gt;Average&lt;/a&gt; and it's only a tiny little app that I did for fun and learning. It's written in &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt; with the micro framework &lt;a href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt;, &lt;a href="http://datamapper.org/doku.php?id=docs"&gt;DataMapper&lt;/a&gt;, &lt;a href="http://haml.hamptoncatlin.com/"&gt;Haml&lt;/a&gt; and published to &lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt; with their &lt;a href="http://en.wikipedia.org/wiki/Git_(software)"&gt;git&lt;/a&gt;-based workflow. Except Ruby I hadn't used any of these before.&lt;br/&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The tools&lt;/strong&gt;&lt;br/&gt;
&lt;a href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; will most likely become my favorite tool for quick web hacks in the futute. I've been using Rubys' built-in CGI support for such before, but Sinatra is beyond compare. It may not be very well suited for anything but small projects but it's hand in glove for admin pages, "reports" or REST services.  Still there are some not that small projects on &lt;a href="http://www.sinatrarb.com/wild.html"&gt;http://www.sinatrarb.com/wild.html&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;
&lt;a href="http://datamapper.org/"&gt;DataMapper&lt;/a&gt; is an &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping"&gt;ORM&lt;/a&gt; and at glance it looks a lot like &lt;a href="http://en.wikipedia.org/wiki/ActiveRecord_(Rails)"&gt;ActiveRecord&lt;/a&gt; but it feels more &lt;a href="http://www.actsasflinn.com/2009/01/02/5-reasons-datamapper-will-deprecate-activerecord"&gt;"pure"&lt;/a&gt;. I really like that it uses regular Ruby classes (and methods, no method_missing magic) that you&lt;a href="http://datamapper.org/doku.php?id=docs:properties"&gt; include DataMapper&lt;/a&gt; to. Sadly the documentation is terrible, it's unstructured and missing some crucial bits. Hopefully that will change in the near future and since it's a wiki anyone can help.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://haml.hamptoncatlin.com/tutorial/"&gt;Haml&lt;/a&gt; is a markup language that generates HTML/XHTML. It makes it very easy to create fully validating XHTML pages. Some parts of Hamls felt kind of strange but after using it for a couple of hours it all seemed to fall into place and I started to like it more and more by the minute. As a disclaimer I have to admit to only have created 8-9 simple &lt;a href="http://haml.hamptoncatlin.com/docs/rdoc/files/FAQ.html"&gt;Haml&lt;/a&gt; templates ever.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt; is a distributed revision control tool. It's really fast, faster than any &lt;a href="http://en.wikipedia.org/wiki/Software_configuration_management"&gt;SCM&lt;/a&gt; I've ever used. Git was initially developed by Linus Torvalds and &lt;a href="http://github.com/"&gt;http://github.com/&lt;/a&gt; seems to be a driving force of adoption.&lt;br/&gt;
&lt;br/&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt; is very impressive! Unparalleled ease of deployment and if you need more power just &lt;a href="http://heroku.com/pricing#blossom-1"&gt;slide the &amp;quot;dyno slider&amp;quot;&lt;/a&gt;! Heroku is free as long as you only use one &lt;a href="http://heroku.com/how/dynos"&gt;dyno&lt;/a&gt;, but if you need more "CPUs", backups, more than 5MB and so on, there's a fee.&lt;br/&gt;&lt;br/&gt;&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Under the hood&lt;/b&gt;
&lt;br/&gt;
&lt;a href="http://average.heroku.com/"&gt;Average&lt;/a&gt;&amp;nbsp;doesn't do much but to its defense it does it in few lines of code. One single Ruby file and some views:&lt;br/&gt;
&lt;font face=Consolas size=1&gt;$ wc -l average.rb&lt;br/&gt;&amp;nbsp;&amp;nbsp;196 average.rb&lt;br/&gt;$ wc -l views/*.haml&lt;br/&gt;&amp;nbsp;&amp;nbsp;6 views/average.haml&lt;br/&gt;&amp;nbsp;19 views/index.haml&lt;br/&gt;&amp;nbsp;25 views/new.haml&lt;br/&gt;&amp;nbsp;&amp;nbsp;9 views/not&lt;em&gt;enough&lt;/em&gt;data.haml&lt;br/&gt;&amp;nbsp;13 views/poll.haml&lt;br/&gt;&amp;nbsp;16 views/show.haml&lt;br/&gt;&lt;/font&gt;
284 rows total.
&lt;br/&gt;And there's nothing more to it because the data model is included in the average.rb:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span style="color:#080;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#B06;font-weight:bold"&gt;Average&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span style="color:#036;font-weight:bold"&gt;DataMapper&lt;/span&gt;::&lt;span style="color:#036;font-weight:bold"&gt;Resource&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:id&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;Integer&lt;/span&gt;, &lt;span style="color:#A60"&gt;:serial&lt;/span&gt; =&amp;gt; &lt;span style="color:#038;font-weight:bold"&gt;true&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:name&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;String&lt;/span&gt;, &lt;span style="color:#A60"&gt;:length&lt;/span&gt; =&amp;gt; &lt;span style="color:#00D;font-weight:bold"&gt;50&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:unit&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;String&lt;/span&gt;, &lt;span style="color:#A60"&gt;:length&lt;/span&gt; =&amp;gt; &lt;span style="color:#00D;font-weight:bold"&gt;50&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:what&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;String&lt;/span&gt;, &lt;span style="color:#A60"&gt;:length&lt;/span&gt; =&amp;gt; &lt;span style="color:#00D;font-weight:bold"&gt;50&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:public&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;Boolean&lt;/span&gt;, &lt;span style="color:#A60"&gt;:default&lt;/span&gt; =&amp;gt; &lt;span style="color:#038;font-weight:bold"&gt;true&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:avgthreshold&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;Integer&lt;/span&gt;, &lt;span style="color:#A60"&gt;:default&lt;/span&gt; =&amp;gt; &lt;span style="color:#00D;font-weight:bold"&gt;0&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:cryptokey&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;String&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:adminkey&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;String&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:allow_multiple&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;Boolean&lt;/span&gt;, &lt;span style="color:#A60"&gt;:default&lt;/span&gt; =&amp;gt; &lt;span style="color:#038;font-weight:bold"&gt;false&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  has n, &lt;span style="color:#A60"&gt;:values&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;class&lt;/span&gt; &lt;span style="color:#B06;font-weight:bold"&gt;Value&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span style="color:#036;font-weight:bold"&gt;DataMapper&lt;/span&gt;::&lt;span style="color:#036;font-weight:bold"&gt;Resource&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:id&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;Serial&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:value&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;Float&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  property &lt;span style="color:#A60"&gt;:valuekey&lt;/span&gt;, &lt;span style="color:#036;font-weight:bold"&gt;String&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  belongs_to &lt;span style="color:#A60"&gt;:average&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;br/&gt;
I only had to type one single SQL statement: &lt;br/&gt;
&lt;font face=Consolas size=2&gt;CREATE DATABASE average;&lt;/font&gt;&lt;br/&gt;
The tables were created by executing &lt;font face=Consolas size=2&gt;DataMapper.auto_migrate!&lt;/font&gt; (in irb), it's also possible to migrate table by table: &lt;font face=Consolas size=2&gt;Average.auto_migrate!&lt;/font&gt;. Migrate drops the table so if you want to keep the data you can use &lt;font face=Consolas size=2&gt;Averages.auto_upgrade!&lt;/font&gt;. It's real easy and powerful.&lt;br/&gt;
Heroku also has a console and there you can run Ruby code in the running production enviroment.&lt;br/&gt;
&lt;font face=Consolas size=2&gt;
$ heroku console&lt;br/&gt;
&amp;gt;&amp;gt; DataMapper.auto_migrate!&lt;br/&gt;
&lt;/font&gt;&lt;br/&gt;
To push your local database to the server just:&lt;br/&gt;&lt;font face=Consolas size=2&gt;
$ heroku db:push mysql://user:pwd@localhost/average&lt;br/&gt;&lt;/font&gt;
(Heroku runs PostgreSQL but the above translates from a plethora of  databases. I got some kind of problem with Booleans from MySQL though.)&lt;br/&gt;For ActiveRecord there's rake db:...
&lt;br/&gt;&lt;br/&gt;
A typical Sinatra Route (a HTTP method paired with a URL matching pattern) could look something like this:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;get &lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;span style=""&gt;/&lt;/span&gt;&lt;span style="color:#710"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span style="color:#33B"&gt;@avgs&lt;/span&gt;=&lt;span style="color:#036;font-weight:bold"&gt;Average&lt;/span&gt;.all(&lt;span style="color:#A60"&gt;:public&lt;/span&gt; =&amp;gt; &lt;span style="color:#038;font-weight:bold"&gt;true&lt;/span&gt;, &lt;span style="color:#A60"&gt;:limit&lt;/span&gt; =&amp;gt; &lt;span style="color:#00D;font-weight:bold"&gt;25&lt;/span&gt;, &lt;span style="color:#A60"&gt;:order&lt;/span&gt; =&amp;gt; [&lt;span style="color:#A60"&gt;:id&lt;/span&gt;.desc])&lt;tt&gt;
&lt;/tt&gt;  haml &lt;span style="color:#A60"&gt;:index&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span style="color:#080;font-weight:bold"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;br/&gt;
My views are written in Haml and it looks something like this:&lt;/p&gt;

&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;%h1= &lt;span style="color:#33B"&gt;@avg&lt;/span&gt;.name&lt;tt&gt;
&lt;/tt&gt;%p== &lt;span style="color:#036;font-weight:bold"&gt;The&lt;/span&gt; average &lt;span style="color:#666"&gt;#{@avg.what} is #{average} #{@avg.unit} and the sample size is #{sample_size}.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;- &lt;span style="color:#080;font-weight:bold"&gt;if&lt;/span&gt; &lt;span style="color:#33B"&gt;@done&lt;/span&gt;==&lt;span style="color:#038;font-weight:bold"&gt;false&lt;/span&gt; &lt;span style="color:#080;font-weight:bold"&gt;then&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  %a{&lt;span style="color:#A60"&gt;:href&lt;/span&gt;=&amp;gt;&lt;span style="background-color:#fff0f0;color:#D20"&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;span style=""&gt;/poll/&lt;/span&gt;&lt;span style="color:#710"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;+&lt;span style="color:#33B"&gt;@avg&lt;/span&gt;.cryptokey} &lt;span style="color:#036;font-weight:bold"&gt;Add&lt;/span&gt; value&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

&lt;p&gt;&lt;br/&gt;
Heroku uses git to publish the applications and the workflow is:&lt;br/&gt;&lt;font face=Consolas size=2&gt;
git add.&lt;br/&gt;
git commit -m &amp;quot;added a before filter&amp;nbsp;for charset utf-8&amp;quot;&lt;br/&gt;
git push heroku&lt;br/&gt;&lt;/font&gt;
&lt;br/&gt;
PS. Peter, look, it validates! &lt;a href="http://validator.w3.org/check?uri=http://average.heroku.com"&gt;http://validator.w3.org/check?uri=http%3A%2F%2Faverage.heroku.com&lt;/a&gt; :) DS&lt;/p&gt;</description>
      <pubDate>Thu, 11 Jun 2009 23:03:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:9e02d487-6a0f-411a-a111-42119d2b76ea</guid>
      <author>Jonas Elfström</author>
      <link>http://alicebobandmallory.blogdns.com/articles/2009/06/11/an-average-application-in-the-clouds</link>
      <category>Ruby</category>
    </item>
    <item>
      <title>Unit testing strains</title>
      <description>&lt;p&gt;I've felt it and I've heard it from colleagues several times. Writing unit tests can be hard work. Especially adding unit test to an existing code base is, at best, cumbersome. Also it's one of those things with delayed gratification. Sometimes it's not even you that will benefit from them being there because the biggest win can be long down the road, when changes to the system has to be made. &lt;/p&gt;

&lt;p&gt;Tests may seem to be isolated and it's even considered a good thing to keep them that way. Even so the tests of your application has a correlation to what the system aims to do on a bigger scale.  This one of the things &lt;a href="http://en.wikipedia.org/wiki/Behavior_driven_development"&gt;BDD&lt;/a&gt;  focuses on. I think that one of the biggest advantages is that you in one process writes a specification and tests that ensures that the spec. is met. Testing becomes a natural part of the development process. This way it clearly shows that BDD and  &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;TDD&lt;/a&gt; are design processes and that it's certainly not all about adding unit tests.&lt;/p&gt;

&lt;p&gt;Find out more about BDD on: &lt;a href="BehaviourDrivenDevelopment"&gt;http://behaviour-driven.org&lt;/a&gt;&lt;br/&gt;
&lt;em&gt;It must be stressed that BDD is a rephrasing of existing good practice, it is not a radically new departure. Its aim is to bring together existing, well-established techniques under a common banner and with a consistent and unambiguous terminology.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For Ruby &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; has almost become the de facto standard for BDD. The concepts Story, Scenario, and Test feels natural and the syntax is short and easy to read.&lt;/p&gt;

&lt;p&gt;In languages like Java or C# the tests often becomes much more cluttered and some of that clutter is the extra code that comes with static typing. I believe that dynamically typed and overall dynamic languages like Ruby or Python could find a nice little niche here. They could become &lt;a href="http://en.wikipedia.org/wiki/Domain-specific_programming_language"&gt;DSL's&lt;/a&gt; for testing.&lt;/p&gt;

&lt;p&gt;RSpec is on it's way for .NET/C# via &lt;a href="http://en.wikipedia.org/wiki/IronRuby"&gt;IronRuby&lt;/a&gt; and for Java via &lt;a href="http://jruby.codehaus.org/"&gt;JRuby&lt;/a&gt; but don't hold your breath because they are still in alpha and beta.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.NET / C#&lt;/strong&gt;&lt;br/&gt;
&lt;a href="http://rubydoes.net/2008/02/21/testing-net-with-ironrubys-mini_rspecrb/"&gt;Testing .NET with IronRuby...&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://bgeek.net/2008/02/14/nspecify-rspec-well-closer-anyway/"&gt;NSpecify =&gt; RSpec… well closer anyway&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Java&lt;/strong&gt;&lt;br/&gt;
&lt;a href="http://pivots.pivotallabs.com/users/pzabelin/blog/articles/375-functional-tests-for-java-project-rspec-jruby"&gt;Java Functional Testing with JRuby and RSpec&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://jtestr.codehaus.org/"&gt;JtestR&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ruby&lt;/strong&gt;&lt;br/&gt;
&lt;a href="http://socialface.com/slapp/"&gt;Slapp&lt;/a&gt; - A simple chat wall Merb tutorial. With nice exampes of using RSpec.&lt;br/&gt;
&lt;a href="http://www.ibm.com/developerworks/web/library/wa-rspec/"&gt;Behavior-driven testing with RSpec&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ASP.NET MVC&lt;/strong&gt;&lt;br/&gt;
&lt;a href="http://blogs.msdn.com/webdevtools/archive/2008/03/06/asp-net-mvc-test-framework-integration-demo.aspx"&gt;ASP.NET MVC Test Framework Integration Walkthrough&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://www.asp.net/learn/3.5-extensions-videos/video-271.aspx"&gt;MVC Preview - Testing&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx"&gt;ASP.NET MVC Session at Mix08, TDD and MvcMockHelpers&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 05 May 2008 21:17:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:89da439e-a963-4880-9501-16902abf9b31</guid>
      <author>Jonas Elfström</author>
      <link>http://alicebobandmallory.blogdns.com/articles/2008/05/05/unit-testing-strains</link>
      <category>Ruby</category>
      <category>C#</category>
      <category>Java</category>
    </item>
    <item>
      <title>Blowfish in the URL</title>
      <description>&lt;p&gt;Sometimes you do not want to show the database id for a row in the URL. The reason could be that you do not want someone to be able to scan through all the data.&lt;/p&gt;

&lt;p&gt;One solution is to use &lt;a href="http://en.wikipedia.org/wiki/Globally_Unique_Identifier"&gt;GUID's&lt;/a&gt; but they have drawbacks and one of them is that they add a considerable length to the URL. The shortest URL-safe representation of a GUID I've seen is &lt;a href="http://tools.assembla.com/breakout/wiki/FreeSoftware"&gt;22 characters&lt;/a&gt; but usually they are 36 characters.&lt;/p&gt;

&lt;p&gt;Depending on how your id's are implemented a much shorter way could be to simply to encrypt them.&lt;/p&gt;

&lt;p&gt;Here's a &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt;-example that Blowfish encrypts, Base64 encodes and URL-encodes an integer value. You can get crypt as a gem:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gem install crypt&lt;/code&gt;&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;rubygems&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;crypt/blowfish&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Base64&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;blowfish&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Crypt&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Blowfish&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;A key up to 56 bytes long&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;
&lt;span class="ident"&gt;plainId&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;123456&lt;/span&gt;
&lt;span class="ident"&gt;encryptedBlock&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;blowfish&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;encrypt_block&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;plainId&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;ljust&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;8&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;
&lt;span class="ident"&gt;idForURL&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;URI&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;escape&lt;/span&gt;&lt;span class="punct"&gt;((&lt;/span&gt;&lt;span class="constant"&gt;Base64&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;encode64&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;encryptedBlock&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;strip&lt;/span&gt;&lt;span class="punct"&gt;))&lt;/span&gt;

&lt;span class="ident"&gt;decryptedId&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;blowfish&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;decrypt_block&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;Base64&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;decode64&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;URI&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;unescape&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;idForURL&lt;/span&gt;&lt;span class="punct"&gt;))).&lt;/span&gt;&lt;span class="ident"&gt;strip&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_i&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The .ljust(8) is because &lt;a href="http://www.schneier.com/blowfish.html"&gt;Blowfish&lt;/a&gt; is a 64-bit block &lt;a href="http://en.wikipedia.org/wiki/Blowfish_(cipher)"&gt;cipher&lt;/a&gt; and the &lt;a href="http://crypt.rubyforge.org/"&gt;Ruby-implementation&lt;/a&gt; does not pad the data itself.&lt;/p&gt;

&lt;p&gt;The id in the URL in this case would be &lt;code&gt;c2PSXWgky40=&lt;/code&gt;. Its 12 characters long (11 if you skip the equal sign) and that's 10 or 24 characters shorter than a GUID. Also there is zero percent chance of a collusion and if you want to you can even decrypt it.&lt;/p&gt;

&lt;p&gt;This is not a super safe implementation but if you start your id's at a random and not too low number you are making it a bit harder for someone to crack the 56-bit key. Actually a truly random and at least 64-bit big number would be a better choice as it would have no connection to the true id at all. You would have to check for uniqueness before storing those in the database though.&lt;/p&gt;</description>
      <pubDate>Thu, 15 Nov 2007 22:38:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:9071a4d1-aaf0-4f17-a796-4ecd65976d64</guid>
      <author>Jonas Elfström</author>
      <link>http://alicebobandmallory.blogdns.com/articles/2007/11/15/blowfish-in-the-url</link>
      <category>Security</category>
      <category>Ruby</category>
      <category>Cryptography</category>
    </item>
  </channel>
</rss>
