<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>The Code Files</title><link href="/blog/" rel="alternate"></link><link href="/blog/feeds/all.atom.xml" rel="self"></link><id>/blog/</id><updated>2014-09-12T00:00:00-06:00</updated><entry><title>Full Disclosure vs. Coordinated Disclosure</title><link href="/blog/full-disclosure-vs-coordinated-disclosure.html" rel="alternate"></link><updated>2014-09-12T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2014-09-12:full-disclosure-vs-coordinated-disclosure.html</id><summary type="html">&lt;p&gt;With the exception of the AntiSec movement, most researchers agree that
vulnerabilities and exploits should be published &lt;em&gt;eventually&lt;/em&gt; so that we can
learn from them. But &lt;em&gt;when&lt;/em&gt; should we publish them?&lt;/p&gt;
&lt;p&gt;Those who practice &amp;quot;Coordinated Disclosure&amp;quot; notify vendors of vulnerabilities
privately, giving them time to patch their software and send out an update. They
argue that keeping the vulnerability secret from the public makes it less likely
that the users running the vulnerable software will be exploited before a patch
is released.&lt;/p&gt;
&lt;p&gt;Proponents of &amp;quot;Full Disclosure&amp;quot; argue that vulnerabilities (and even exploits)
should be published as widely as possible as soon as they are found. One reason
is that giving advance notice to any set of people is a risk. People who know
about the vulnerability can exploit it while users are still in the dark. When
vulnerabilities are disclosed immediately, users can at least make the concious
decision to stop using the software until a patch is released. In economic
terms, users who don't know about a vulnerability can't user their wallets
pressure the vendor into developing a patch, and as a result vendors might leave
users vulnerable while they procrastinate the development of a patch.&lt;/p&gt;
&lt;p&gt;There are many more arguments and counter-arguments on both sides. It's not
always clear which practice is best. It usually depends on the specific case.
But in all cases, the right option is the one that &lt;em&gt;reduces the actual count of
malicious exploitation&lt;/em&gt;. This is something that could be tested empirically for
different classes of vulnerability.&lt;/p&gt;
</summary><category term="disclosure"></category></entry><entry><title>"I have nothing to hide."</title><link href="/blog/i-have-nothing-to-hide.html" rel="alternate"></link><updated>2014-06-28T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2014-06-28:i-have-nothing-to-hide.html</id><summary type="html">&lt;ul class="simple"&gt;
&lt;li&gt;I have nothing to hide.&lt;/li&gt;
&lt;li&gt;I have not, nor will I ever, do anything wrong.&lt;/li&gt;
&lt;li&gt;I have not, nor will I ever, do anything wrong, as defined by the government.&lt;/li&gt;
&lt;li&gt;I have only ever done, and only ever will do, things defined as right by the
government.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By stating that you &amp;quot;have nothing to hide&amp;quot;, you are admitting your behaviour is
constrained by the someone else's arbitrary definition of &amp;quot;wrong.&amp;quot; Maybe you're
fine with that, but ask yourself two questions:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Do you really know what's defined as &amp;quot;wrong&amp;quot;?&lt;/li&gt;
&lt;li&gt;Could the meaning of &amp;quot;wrong&amp;quot; ever change?&lt;/li&gt;
&lt;/ol&gt;
</summary><category term="surveillance"></category></entry><entry><title>Switching to Pelican</title><link href="/blog/switching-to-pelican.html" rel="alternate"></link><updated>2014-06-10T09:56:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2014-06-10:switching-to-pelican.html</id><summary type="html">&lt;p&gt;This blog used to be a Ruby on Rails app that I wrote myself. It was way too
time consuming to keep updating Ruby and Ruby on Rails (for security patches),
so I gave up. This blog is now just static &lt;tt class="docutils literal"&gt;.html&lt;/tt&gt; files generated from
&lt;tt class="docutils literal"&gt;.rst&lt;/tt&gt; files with &lt;a class="reference external" href="http://blog.getpelican.com/"&gt;Pelican&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Hopefully I'll find, or create, a better theme soon!&lt;/p&gt;
</summary><category term="blog"></category><category term="meta"></category></entry><entry><title>How to Maximize X in Your Life</title><link href="/blog/how-to-maximize-anything-in-your-life.html" rel="alternate"></link><updated>2013-11-01T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2013-11-01:how-to-maximize-anything-in-your-life.html</id><summary type="html">&lt;p&gt;How to maximize X (success, happiness, skill, or whatever) in your life:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Every week, spend at least an hour reviewing what you did the previous week.
Think of what you could have done better to increase X even more. Apply the
things you find to the next week.&lt;/li&gt;
&lt;li&gt;Every month, spend at least an hour reviewing your review process. Are your
weekly reviews making you improve X? Think about how you could make your
review process better. Do you need more time for the weekly reviews? What
other changes to the reviews can you make so they're more effective? Apply
these changes in the next month.&lt;/li&gt;
&lt;li&gt;Every year, spend at least an hour reviewing your monthly review of review
process. Are your monthly reviews improving the effectiveness of your weekly
reviews? How can you make your monthly reviews better? Apply these changes in
the next year.&lt;/li&gt;
&lt;li&gt;Every 5 years, review the yearly reviews in the same way.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you graph y = X(t) as a curve, the days of your life represent actual
increases in the value of X. The weekly reviews represent increases in the slope
(first derivative) of X(t), making it increase faster. The monthly reviews
increases the rate at which the slope of X(t) increases (second derivative). The
yearly reviews increase the rate at which the rate at which the slope is
increasing (third derivative). The 5-year reviews increase the fourth
derivative, and so on, if you wish to apply more levels of review.&lt;/p&gt;
&lt;p&gt;I believe this process to be the best a human being can do to approximate
exponential growth of some property of themselves within their lifetime.&lt;/p&gt;
</summary><category term="life"></category></entry><entry><title>Enabling TLS v1.1 on Firefox 23</title><link href="/blog/enabling-tls-11-on-firefox-version-23.html" rel="alternate"></link><updated>2013-08-09T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2013-08-09:enabling-tls-11-on-firefox-version-23.html</id><summary type="html">&lt;p&gt;Change the following settings in Firefox's &lt;a class="reference external" href="about:config"&gt;about:config&lt;/a&gt; to enable TLS v1.1.&lt;/p&gt;
&lt;img alt="Enabling TLS 1.1 in Firefox 23" src="https://defuse.ca/images/ff23-tls.png" /&gt;
&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Open a new tab and type &lt;a class="reference external" href="about:config"&gt;about:config&lt;/a&gt; into the address bar.&lt;/li&gt;
&lt;li&gt;Search for tls.version.&lt;/li&gt;
&lt;li&gt;Set security.tls.version.max to 2. This enables TLS 1.1.&lt;/li&gt;
&lt;li&gt;Set security.tls.version.min to 1. This disables SSL 3.0.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Be aware that setting tls.version.max to 3 will enable TLS v1.2 in a future
release of Firefox, but setting it to 3 in version 23 actually makes it fall
back to using &lt;em&gt;only&lt;/em&gt; TLS 1.0. So for now, set it to 2.&lt;/p&gt;
&lt;p&gt;The image was contributed by &lt;a class="reference external" href="https://twitter.com/voodooKobra"&gt;&amp;#64;voodooKobra&lt;/a&gt;.&lt;/p&gt;
</summary><category term="firefox"></category></entry><entry><title>What is DDoS? (Guest Post)</title><link href="/blog/what-is-ddos.html" rel="alternate"></link><updated>2013-05-12T00:00:00-06:00</updated><author><name>Breshie</name></author><id>tag:/blog,2013-05-12:what-is-ddos.html</id><summary type="html">&lt;p&gt;This is a guest post by BreShiE.&lt;/p&gt;
&lt;p&gt;DDoS attacks are becoming more and more frequent in today's world, with any
average person being able to download or purchase such tools from online, public
forums. You may have heard about the self proclaimed hacktivist group
&amp;quot;Anonymous&amp;quot; and their infamous take-downs of websites such as &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Operation_Payback"&gt;MasterCard,
PayPal and The Bank of America&lt;/a&gt;. Well, these websites were taken offline for
a period of time by an attack known as &amp;quot;DDoS&amp;quot;, but what is DDoS?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DDoS&lt;/strong&gt; stands for &lt;strong&gt;Distributed Denial of Service&lt;/strong&gt;. DDoS attacks work by
collecting multiple infected machines or servers with certain scripts, or
malware, intended to send data from the infected server or home connection to
a victims. This means the attacker can overload the victim connection, by
flooding it with loads and loads of dummy data, eventually causing the victim
connection to overload, &amp;quot;knocking&amp;quot; the connection offline and making it
unresponsive. See the below diagram for an example of this:&lt;/p&gt;
&lt;img alt="DDoS diagram" src="/images/breshie-ddos.png" /&gt;
&lt;p&gt;As you can see from the above diagram, the attacker sends a command to the
servers/PCs that are under his/her control, which then send the dummy data to
the victim connection and overloads the connection, making it hard or impossible
for the victim's users to communicate with the victim. There's also what is
known as &amp;quot;DoS&amp;quot; which is often not as strong as a DDoS attack, but if the
attacker is using a server with a strong connection, this attack can still be
devastating. One thing to &lt;strong&gt;note&lt;/strong&gt; would be that there are companies which fight
to prevent this exact attack and that is why you never see big sites like eBay,
YouTube and Google go down. With this &lt;a class="reference external" href="http://www.bbc.co.uk/news/technology-17472447"&gt;huge scare about &amp;quot;hackers being able to
take down the internet&amp;quot;&lt;/a&gt;, it's baloney. The only way it would be possible, is
if the data-centers were to be physically blown up, not DDoS attacks via the
internet.  If you wish to know more on this subject, visit &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Distributed_denial_of_service#Distributed_attack"&gt;Wikipedia's page on
DDoS&lt;/a&gt;&lt;/p&gt;
</summary><category term="ddos"></category></entry><entry><title>Switching Desktops/Workspaces with Mouse Buttons</title><link href="/blog/linux-switch-virtual-desktop-workspace-mouse-button.html" rel="alternate"></link><updated>2013-04-29T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2013-04-29:linux-switch-virtual-desktop-workspace-mouse-button.html</id><summary type="html">&lt;p&gt;I had to uninstall compiz today, and I absolutely can't live without being able
to switch virtual desktops (also known as workspaces) with the buttons on the
side of my mouse. Here's how you do it:&lt;/p&gt;
&lt;p&gt;First, install &lt;strong&gt;xbindkeys&lt;/strong&gt; and &lt;strong&gt;xdotool&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
apt-get install xbindkeys xdotool
&lt;/pre&gt;
&lt;p&gt;Then create a &lt;strong&gt;.xbindkeysrc&lt;/strong&gt; file in your home folder:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
vim ~/.xbindkeysrc
&lt;/pre&gt;
&lt;p&gt;Into this file, put the following:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
# -- Move Right --
# This is the general command that works with any number of workspaces:
# &amp;quot;xdotool set_desktop $(expr $(expr $(xdotool get_desktop) + 1) % $(xdotool get_num_desktops))&amp;quot;
# This is the optimized command for 5 workspaces:
&amp;quot;xdotool set_desktop $(expr $(expr $(xdotool get_desktop) + 1) % 5)&amp;quot;
    b:8

# -- Move Left --
# This is the general command that works with any number of workspaces:
# &amp;quot;xdotool set_desktop $(expr $(expr $(xdotool get_desktop) + $(expr $(xdotool get_num_desktops) - 1)) % $(xdotool get_num_desktops))&amp;quot;
# This is the optimized command for 5 workspaces:
&amp;quot;xdotool set_desktop $(expr $(expr $(xdotool get_desktop) + 4) % 5)&amp;quot;
    b:9
&lt;/pre&gt;
&lt;p&gt;In the above config, replace &amp;quot;8&amp;quot; with the number of the button you want to use
to move right, and &amp;quot;9&amp;quot; with the number of the button you want to use to move
left. If you don't know what the button numbers are, run &amp;lt;b&amp;gt;xev&amp;lt;/b&amp;gt;, press the
one you want while hovering your mouse over the window, and you'll see it in the
output.&lt;/p&gt;
&lt;p&gt;The command that's uncommented works with a 5-workspace setup. If you want it to
work with X desktops either comment that one out and uncomment the general
command, or replace &amp;quot;5&amp;quot; with X and &amp;quot;4&amp;quot; with X - 1.&lt;/p&gt;
&lt;p&gt;Then add &lt;strong&gt;xbindkeys&lt;/strong&gt; (no arguments) to your startup applications. If you want windows to &amp;quot;edge switch&amp;quot; (switch workspaces when you drag them across the side of your screen), look at &lt;a class="reference external" href="http://lifehacker.com/263508/add-screen-actions-with-brightside"&gt;brightside&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Note: &lt;a class="reference external" href="http://forum.pinguyos.com/Thread-HOWTO-Mouse-buttons-to-change-workspaces-in-gnome-shell"&gt;HOWTO: Mouse buttons to change workspaces in gnome-shell&lt;/a&gt; helped me figure out how to do this.&lt;/p&gt;
</summary><category term="xbindkeys"></category></entry><entry><title>[Ruby] Password Training Script</title><link href="/blog/ruby-password-training-script.html" rel="alternate"></link><updated>2013-03-28T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2013-03-28:ruby-password-training-script.html</id><summary type="html">&lt;p&gt;This is a simple Ruby script that helps you memorize a password by making you
type it over and over again. It first breaks the password into chunks of
4 characters, helps you to memorize each chunk, then every consecutive pair of
chunks, then every consecutive triple... and so on, until you're typing the
entire password from memory.&lt;/p&gt;
&lt;p&gt;I was able to completely memorize a 131-bit password (20 printable ASCII
characters, completely random) in about 20 minutes using this script.&lt;/p&gt;
&lt;p&gt;You'll need the 'highline' gem to run this script: &lt;tt class="docutils literal"&gt;gem install highline&lt;/tt&gt;.&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="c1"&gt;# Ruby Password Trainer&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'highline/import'&lt;/span&gt;

&lt;span class="no"&gt;TIMES_TO_TYPE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="no"&gt;CHUNK_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;This is a script that helps you memorize a password.&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;WARNING: Make sure nobody is watching you while you use this script!&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Your password: &amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;gets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chop&lt;/span&gt;
&lt;span class="n"&gt;password_chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="no"&gt;CHUNK_SIZE&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_a&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gets_noecho&lt;/span&gt;
  &lt;span class="n"&gt;ask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clear&lt;/span&gt;
  &lt;span class="nb"&gt;system&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;clear&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;continue?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Round &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; finished. Again? [Y/n] &amp;quot;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;gets&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/^y$/i&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_chunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password_chunks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;password_chunks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;num_chunks&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;portion&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;portion&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Training&lt;/span&gt;
    &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TIMES_TO_TYPE&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Type &lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; times...&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gets_noecho&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt;
        &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;WRONG! You typed &lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
        &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="c1"&gt;# Recall test&lt;/span&gt;
    &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TIMES_TO_TYPE&lt;/span&gt;
    &lt;span class="n"&gt;wrong&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;wrong&lt;/span&gt;
      &lt;span class="n"&gt;clear&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Type the same thing &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; times...&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gets_noecho&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt;
        &lt;span class="n"&gt;wrong&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;gt;&amp;gt; You got &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;TIMES_TO_TYPE&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;TIMES_TO_TYPE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; right.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;wrong&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Try again...&amp;quot;&lt;/span&gt;
      &lt;span class="k"&gt;redo&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;round&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;begin&lt;/span&gt;
  &lt;span class="n"&gt;clear&lt;/span&gt;
  &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;password_chunks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;num_chunks&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_chunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password_chunks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="n"&gt;round&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;continue?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;round&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;
</summary><category term="ruby"></category><category term="passwords"></category></entry><entry><title>[LaTeX] Typesetting Premise and Conclusion Form Arguments</title><link href="/blog/latex-premise-conclusion-form-arguments.html" rel="alternate"></link><updated>2013-02-23T00:00:00-07:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2013-02-23:latex-premise-conclusion-form-arguments.html</id><summary type="html">&lt;p&gt;This is the easiest way I have found to typeset premise and conclusion style
arguments in LaTeX. First, add this to your preamble:&lt;/p&gt;
&lt;pre class="code latex literal-block"&gt;
&lt;span class="k"&gt;\usepackage&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;amssymb&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Then use something like this to typeset the argument:&lt;/p&gt;
&lt;pre class="code latex literal-block"&gt;
&lt;span class="k"&gt;\begin&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;itemize&lt;span class="nb"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;\item&lt;/span&gt;&lt;span class="na"&gt;[1.]&lt;/span&gt; Premise One.
    &lt;span class="k"&gt;\item&lt;/span&gt;&lt;span class="na"&gt;[2.]&lt;/span&gt; Premise Two.
    &lt;span class="k"&gt;\item&lt;/span&gt;&lt;span class="na"&gt;[3.]&lt;/span&gt; Premise Three.
    &lt;span class="k"&gt;\item&lt;/span&gt;&lt;span class="na"&gt;[$\therefore$]&lt;/span&gt; Therefore, Your Conclusion.
&lt;span class="k"&gt;\end&lt;/span&gt;&lt;span class="nb"&gt;{&lt;/span&gt;itemize&lt;span class="nb"&gt;}&lt;/span&gt;
&lt;/pre&gt;
</summary><category term="latex"></category></entry><entry><title>[Ruby] Genetic String Evolver</title><link href="/blog/genetic-string-evolver-in-ruby.html" rel="alternate"></link><updated>2013-02-19T00:00:00-07:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2013-02-19:genetic-string-evolver-in-ruby.html</id><summary type="html">&lt;p&gt;Inspired by &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Weasel_program"&gt;Richard Dawkins' weasel program&lt;/a&gt;, this is a genetic algorithm,
written in Ruby, to evolve the same &amp;quot;METHINKS IT IS LIKE A WEASEL&amp;quot; string. It's
really fun to experiment with changing the probability constants (mutation,
reproduction) and the algorithm in &lt;tt class="docutils literal"&gt;Evolver#advance&lt;/tt&gt;, which advances the
population of strings to the next generation. Have fun!&lt;/p&gt;
&lt;p&gt;The default algorithm works as follows:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Initialize a population of random strings.&lt;/li&gt;
&lt;li&gt;Mutate each string with probability 'mutation_probability'.&lt;/li&gt;
&lt;li&gt;Breed each string with another random string from the population with
probability 'breed_probability', keeping the newborn population separate.&lt;/li&gt;
&lt;li&gt;Kill random newborns until the number of newborns is less than 1/4 of the
size of the main population.&lt;/li&gt;
&lt;li&gt;Select a random half of the main population and replace its weakest (furthest
from the target) members with the remaining newborns.&lt;/li&gt;
&lt;li&gt;Go back to Step 2.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In about 5000-10000 generations, the strongest member of the population
stabilizes to the target string.&lt;/p&gt;
&lt;p&gt;The same algorithm can be applied to other problems, like finding the maximum of
a mathematical function, by just modifying &lt;tt class="docutils literal"&gt;Weasel.rb&lt;/tt&gt;.&lt;/p&gt;
&lt;div class="section" id="sample-output"&gt;
&lt;h2&gt;Sample Output&lt;/h2&gt;
&lt;p&gt;The left column is the population's strongest member. The right column is the
population's weakest member.&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
YAPXMLHQFORHPPNVWF DISTEBZEK -- vs. -- YZLHUURLMPKITAP ZYVTTSIZZCQV (Gen: 0)
YAPXMLHQFORHPPNVWF DISTEBZEK -- vs. -- CXZWQCVCUAZFDOUSZNRCXDQPNENR (Gen: 1)
YAEBXJFACES FVUTYWTLATTIACDY -- vs. -- CXZWQCVCUAZFDOUSZNRCXDQPNENR (Gen: 2)
YAEBXJFACES FVUTYWTLATTIACDY -- vs. -- J ICBDLWUGASSNRS YENZDLVBJ V (Gen: 3)
YAEBXJFACES FVUTYWTLATTIACDY -- vs. -- NJQPSUPJUBEUQGNEBPRCMHIVBJ V (Gen: 4)
YAEBXJFACES FVUTYWTLATTIACDY -- vs. -- NJQPSUPJUBEUQGNEBPRCMHIVBJ V (Gen: 5)
YAEBXJFACES FVUTYWTLATTIACDY -- vs. --  RQPSUPJUBEUQWSFJTJ OWHRTKIM (Gen: 6)
MDLDIGLMBUJPTV LWEC W FMNINL -- vs. -- ZXZNNKDUGWIVLKARQLMDKCIZ FGW (Gen: 7)
MDLDIGLMBUJPTV LWEC W FMNINL -- vs. -- ZXZNNKDUGWIVLKARQLMDKCIZ FGW (Gen: 8)
...
MDPXKNIS MVHXZ LHCC W ODACEL -- vs. -- MDLDMFQS MVHCZ LHCCGW IQACDY (Gen: 100)
MDPXKNIS MVHXZ LHCC W ODACEL -- vs. -- MDJDIFVS M DAS HHXC W TSACEL (Gen: 101)
MDPXKNIS MVHXZ LHCC W ODACEL -- vs. -- MDJDMNQS MVGXZ LHCC W FQACDL (Gen: 102)
MADIMNQS MVDXZ LHCE W ODACEL -- vs. -- MDJDMNQS MVGXZ LHEC W FMACIL (Gen: 103)
MDPXKNQS MVDAS HHCE W ODACEL -- vs. -- MDJDMNQS MVGXZ LHEC W FMACIL (Gen: 104)
MDPXKNQS MVDAS HHCE W ODACEL -- vs. -- MAPXYNCM MVHXZ LHTC D DQACIL (Gen: 105)
...
METHINIS ITHIS LHKE A VMAQEL -- vs. -- METHINIS IVHWS LHKEXA VMAQEL (Gen: 400)
METHINIS ITHIS LHKE A VMAQEL -- vs. -- METHINIS RVHIS LHKEEA VMAQEL (Gen: 401)
METHINIS ITHIS LHKE A VMAQEL -- vs. -- METHINIS RVHIS LHKEEA VMAQEL (Gen: 402)
METHINIS ITHIS LHKE A VMACEL -- vs. -- METHINIS IVHWS LHKEXA VMAQEL (Gen: 403)
METHINIS ITHIS LHKE A VMAQEL -- vs. -- METHFNIS RVHIS LHKE A VMAQEL (Gen: 404)
METHINIS ITHIS LHKE A VMAQEL -- vs. -- METHFNIS RRHIS LHKE A VMAQEL (Gen: 405)
...
METHINIS IV IS LHKE A WMAQEL -- vs. -- MVTHINIS IV IS QHKE AMVMAQEL (Gen: 800)
METHINIS IV IS LHKE A WMAQEL -- vs. -- METUINIS IV IS LHKE AMVMEQEL (Gen: 801)
METHINIS IV IS LHKE A WMAQEL -- vs. -- METUINIS IV IS LHKE AMVMEQEL (Gen: 802)
METHINIS IV IS LHKE A WMAQEL -- vs. -- METUINIS IV IS LHKE AMVMEQEL (Gen: 803)
METHINIS IV IS LHKE A WMAQEL -- vs. -- METHINIS IVQISKLHKE A VMAQEL (Gen: 804)
METHINIS IV IS LHKE A WMAQEL -- vs. -- METCINIS IV RS LHKK A WMAQEL (Gen: 805)
...
METHINKS IT IS LIKE A WEAWEL -- vs. -- ROTHINKS IT IS LIKE A WEAHEL (Gen: 5106)
METHINKS IT IS LIKE A WEAWEL -- vs. -- MOTHINKS ITSIS VIKE A WEAWEL (Gen: 5107)
METHINKS IT IS LIKE A WEAWEL -- vs. -- MOTHINKS ITSIS VIKE A WEAWEL (Gen: 5108)
METHINKS IT IS LIKE A WEAWEL -- vs. -- METHINKSOIT IS LIKE A WEAWEL (Gen: 5109)
METHINKS IT IS LIKE A WEASEL -- vs. -- METHINKSOIT IS LIKE A WEAWEL (Gen: 5110)
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="main-rb"&gt;
&lt;h2&gt;Main.rb&lt;/h2&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'./Evolver.rb'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'./Weasel.rb'&lt;/span&gt;

&lt;span class="n"&gt;evolver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Evolver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="no"&gt;Weasel&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;evolver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setup&lt;/span&gt;

&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;evolver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; -- vs. -- &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;evolver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;worst&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (Gen: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;) &lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="n"&gt;evolver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;advance&lt;/span&gt;
  &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="evolver-rb"&gt;
&lt;h2&gt;Evolver.rb&lt;/h2&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="c1"&gt;# WARNING: I have never even read `On the Origin of Species` so do not mistake&lt;/span&gt;
&lt;span class="c1"&gt;# this horrible code to be anything like what happens in nature.&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Evolver&lt;/span&gt;

  &lt;span class="kp"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:population&lt;/span&gt;
  &lt;span class="kp"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:population_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:mutation_probability&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:breed_probability&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;entity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;population_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;mutation_probability&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;07&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;breed_probability&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;population_size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;entity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;advance&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;mutation_probability&lt;/span&gt;
        &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mutate&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;newborns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;breed_probability&lt;/span&gt;
        &lt;span class="n"&gt;newborns&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;population&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Limit the number of newborns to at most 1/4 of the population size.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;newborns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;
      &lt;span class="n"&gt;newborns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shuffle!&lt;/span&gt;
      &lt;span class="n"&gt;newborns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newborns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Select a random half of the population to be candidates for dying.&lt;/span&gt;
    &lt;span class="n"&gt;killed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shuffle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Sort them by goodness value in increasing order.&lt;/span&gt;
    &lt;span class="n"&gt;killed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sort!&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;goodness&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;goodness&lt;/span&gt;
        &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;goodness&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;goodness&lt;/span&gt;
        &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Replace the weakest death candidates with the newborns.&lt;/span&gt;
    &lt;span class="n"&gt;newborns&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_with_index&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;subj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;killed&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subj&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;best&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inject&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;goodness&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;goodness&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;worst&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;population&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inject&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;goodness&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;goodness&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="weasel-rb"&gt;
&lt;h2&gt;Weasel.rb&lt;/h2&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Weasel&lt;/span&gt;
  &lt;span class="kp"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:str&lt;/span&gt;

  &lt;span class="no"&gt;ALPHABET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ABCDEFGHIJKLMNOPQRSTUVWXYZ &amp;quot;&lt;/span&gt;
  &lt;span class="no"&gt;TARGET&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;METHINKS IT IS LIKE A WEASEL&amp;quot;&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;
    &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="no"&gt;TARGET&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ALPHABET&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ALPHABET&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;Weasel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mutate&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;str&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;str&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ALPHABET&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ALPHABET&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;organism&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;split&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;str&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;front&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;str&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;back&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;organism&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;split&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;organism&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;Weasel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;front&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;back&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;goodness&lt;/span&gt;
    &lt;span class="n"&gt;hamming&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;str&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;hamming&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;str&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ord&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="no"&gt;TARGET&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ord&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;hamming&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_s&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;str&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
</summary><category term="evolution"></category></entry><entry><title>Windows Magnifier Hack</title><link href="/blog/windows-magnifier-password-reset.rst.html" rel="alternate"></link><updated>2013-02-19T00:00:00-07:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2013-02-19:windows-magnifier-password-reset.rst.html</id><summary type="html">&lt;p&gt;Steps to reset a Windows account password given physical access to the box:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Boot a Linux live cd and mount C:somewhere.&lt;/li&gt;
&lt;li&gt;Find magnifier.exe (somewhere in System32) and replace it with cmd.exe.&lt;/li&gt;
&lt;li&gt;Boot to the Windows login screen.&lt;/li&gt;
&lt;li&gt;Press WinKey + U&lt;/li&gt;
&lt;li&gt;Start the magnifier, which should run cmd.exe.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://support.microsoft.com/kb/149427"&gt;Change the password in the Command Prompt&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that this will destroy all data encrypted with &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Encrypting_File_System"&gt;EFS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I'm not sure who thought of this first, but if I knew, I would credit them here.&lt;/p&gt;
</summary><category term="windows"></category></entry><entry><title>Factorization Correlation Experimentation Tool</title><link href="/blog/factorization-genetic-algorithm-correlation.html" rel="alternate"></link><updated>2013-01-25T00:00:00-07:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2013-01-25:factorization-genetic-algorithm-correlation.html</id><summary type="html">&lt;p&gt;Here's a Ruby script to experiment with correlations that may be useful in
developing a genetic (evolutionary) algorithm for factoring the product of two
primes. The comments explain it:&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# Let C = F1 * F2, where F1 and F2 are primes.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# This script gives a visual aid to help determine if the value of some function&lt;/span&gt;
&lt;span class="c1"&gt;# (specified by the user) on a test integer is correlated with the test&lt;/span&gt;
&lt;span class="c1"&gt;# integer's hamming distance from min(F1, F2).&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# If such a correlation exists, it may be possible to use that function to&lt;/span&gt;
&lt;span class="c1"&gt;# calculate the 'fitness' of test integers in a genetic (evolutionary) algorithm&lt;/span&gt;
&lt;span class="c1"&gt;# for factoring C.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Of course the function must be efficiently computable without knowing the&lt;/span&gt;
&lt;span class="c1"&gt;# factorization of C.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Set the function by modifying the 'function' method below. Set the F1 and F2&lt;/span&gt;
&lt;span class="c1"&gt;# by modifying the 'F1' and 'F2' variables below. C is calculated from F1 and&lt;/span&gt;
&lt;span class="c1"&gt;# F2.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Some interesting functions are:&lt;/span&gt;
&lt;span class="c1"&gt;#   - The hamming distance between C and the test integer.&lt;/span&gt;

&lt;span class="c1"&gt;# If you don't have the gnuplot gem, run `gem install gnuplot`&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'gnuplot'&lt;/span&gt;

&lt;span class="no"&gt;F1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8831&lt;/span&gt;
&lt;span class="no"&gt;F2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12479&lt;/span&gt;

&lt;span class="c1"&gt;# Set this to true to make the multiplicity of points visible by adding random&lt;/span&gt;
&lt;span class="c1"&gt;# variations in their horizontal position.&lt;/span&gt;
&lt;span class="no"&gt;JITTER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;

&lt;span class="no"&gt;F_DESC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;HammingDistance(test, C)&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;composite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;potentialFactor&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;hammingDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;composite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;potentialFactor&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ----------------------------------------------------------------------------&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hammingDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;1&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;

&lt;span class="n"&gt;compareFactor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;F1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;F2&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;
&lt;span class="n"&gt;composite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;F1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;F2&lt;/span&gt;

&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="no"&gt;Math&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;composite&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ceil&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;composite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;hammingDistance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compareFactor&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;100_000&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="ss"&gt;Gnuplot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:open&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="ss"&gt;Gnuplot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Plot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;gp&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;C = F1 * F2 where F1 and F2 are prime. &lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;n&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="s2"&gt;&amp;quot;C = &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;F1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;F2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; F1 = &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;F1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; F2 = &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;F2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ylabel&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;HammingDistance(test, min(F1, F2))&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlabel&lt;/span&gt; &lt;span class="no"&gt;F_DESC&lt;/span&gt;
    &lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xrange&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;[0:]&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;yrange&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;[0:]&amp;quot;&lt;/span&gt;

    &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;JITTER&lt;/span&gt;
      &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="ss"&gt;Gnuplot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:DataSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;JITTER&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;dots&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;points&amp;quot;&lt;/span&gt;
      &lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notitle&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
</summary><category term="factorization"></category></entry><entry><title>Vim: Make Rainbow Parentheses Work in PHP</title><link href="/blog/vim-rainbow-parentheses-work-in-php.html" rel="alternate"></link><updated>2012-12-22T00:00:00-07:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-12-22:vim-rainbow-parentheses-work-in-php.html</id><summary type="html">&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; What I propose here doesn't actually fix it, it still fails when
there's a greater-than sign inside an if statement. I have spent over 8 hours
trying to get this to work and that is too much, so I am giving up. If you find
a solution, please email it to me.&lt;/p&gt;
&lt;p&gt;I use this script to get rainbow parentheses in Vim:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/kien/rainbow_parentheses.vim"&gt;https://github.com/kien/rainbow_parentheses.vim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.vim.org/scripts/script.php?script_id=3772"&gt;http://www.vim.org/scripts/script.php?script_id=3772&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It colors nested parentheses like this:&lt;/p&gt;
&lt;img alt="Vim Rainbow Parentheses" src="https://defuse.ca/images/rainbow.png" /&gt;
&lt;p&gt;Unfortunately, it doesn't work with PHP, because the PHP syntax file only allows
its own syntax regions to appear inside the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;lt;?php&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;?&amp;gt;&lt;/span&gt;&lt;/tt&gt; tags. The fix
is simple:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Copy the 'system' php syntax file (usually
&lt;tt class="docutils literal"&gt;/usr/local/share/vim/vim73/syntax/php.vim&lt;/tt&gt;) to your personal
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.vim/syntax&lt;/span&gt;&lt;/tt&gt; folder (create it if it does not exist).&lt;/li&gt;
&lt;/ol&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Edit &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.vim/syntax/php.vim&lt;/span&gt;&lt;/tt&gt;, find the line that starts with &lt;tt class="docutils literal"&gt;syn cluster
phpClTop&lt;/tt&gt; and add &lt;tt class="docutils literal"&gt;level16&lt;/tt&gt; to the end of the 'contains' list on that
line. If you have set &lt;tt class="docutils literal"&gt;g:rbpt_max&lt;/tt&gt; in your .vimrc, then you will need to
change the &amp;quot;16&amp;quot; to that value.&lt;/li&gt;
&lt;/ol&gt;
</summary><category term="vim"></category></entry><entry><title>Encrypted Automatic Backups with Public Key Cryptography</title><link href="/blog/encrypted-automatic-backups-with-pkc.html" rel="alternate"></link><updated>2012-12-16T00:00:00-07:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-12-16:encrypted-automatic-backups-with-pkc.html</id><summary type="html">&lt;p&gt;Here's how to do encrypted automated backups without having to store the
password in the backup script. The script should be self-explanatory (after all,
it is 50 lines of comments for just one real line of code).&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
&lt;span class="c"&gt;#!/bin/bash
# File name: backup.sh
# This script automates the process of encrypting a directory for backup.
#
# Instead of using normal password encryption, we take advantage of public-key
# cryptography so that you don't need to include the password in the encryption
# script. This is required if you want to have files automatically encrypted
# with a password remembered only by your biological brain.
#
# It requires a bit of setup:
#
# 1. Generate a public/private key pair (as the user that will run this script):
#   - Run,
#      $ gpg --s2k-cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-mode 3  \
#        --s2k-count 65011712 --gen-key
#   - Choose the &amp;quot;RSA and RSA&amp;quot; key type.
#   - Choose 4096 (or greater) as the key size.
#   - Enter an expiration time of 0 (never expires)
#   - Give the key a name (enter 'invalid&amp;#64;invalid.invalid' for the email).
#   - Enter a password. This is the password that you will need to decrypt the
#     backup files.
#
# 2. Modify the constants in this script:
#   - DIRECTORY:
#       Set this to the folder you want to automatically encrypt.
#   - GPG_RECIPIENT
#       Set this to the ID of the public key generated in step 1.
#       You can find the ID by running
#           $ gpg --list-keys
#       It is the 8-digit hexadecimal number on the 'pub' line corresponding to
#       your key.
#   - OUTPUT_FILE
#       Where to put the encrypted GPG file.
#       If the file already exists, it will be overwritten.
#
# 3. Backup your public key and (encrypted) private key.
#   To decrypt the file that this script generates, you will need the private
#   key and the password you gave in step 1, so it is a good idea to make
#   a backup of your key pair.
#
#   To backup your public key:
#       $ gpg -a --export NAME &amp;gt; public_key.txt
#   To backup your private key:
#       $ gpg -a --export-secret-keys NAME &amp;gt; private_key.txt
#   ...where NAME is part of the name you gave in step 1.
#
#   Because the private key is encrypted with the password, it is safe to store
#   the key backups with the backup file (or even publish them).
#
# DECRYPTING:
#   To decrypt the file generated by this script, run:
#       $ gpg -d -o decrypted.tar &amp;lt;backup file&amp;gt;
#       $ tar xvf decrypted.tar
&lt;/span&gt;
&lt;span class="nb"&gt;readonly &lt;/span&gt;&lt;span class="nv"&gt;DIRECTORY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./testing                    &lt;span class="c"&gt;# Directory to encrypt.
&lt;/span&gt;&lt;span class="nb"&gt;readonly &lt;/span&gt;&lt;span class="nv"&gt;GPG_RECIPIENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;EAD91475                 &lt;span class="c"&gt;# Public key ID.
&lt;/span&gt;&lt;span class="nb"&gt;readonly &lt;/span&gt;&lt;span class="nv"&gt;OUTPUT_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/encrypted.tar.gpg     &lt;span class="c"&gt;# Encrypted file path.
&lt;/span&gt;
tar cf - -C &lt;span class="nv"&gt;$DIRECTORY&lt;/span&gt; . | &lt;span class="se"&gt;\
&lt;/span&gt;    gpg -z 9 --batch --yes --encrypt --recipient &lt;span class="nv"&gt;$GPG_RECIPIENT&lt;/span&gt; --output &lt;span class="nv"&gt;$OUTPUT_FILE&lt;/span&gt;
&lt;/pre&gt;
</summary><category term="backups"></category></entry><entry><title>Increasing Collisions in Password Hashing</title><link href="/blog/increasing-collisions-in-password-hashing.html" rel="alternate"></link><updated>2012-12-11T00:00:00-07:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-12-11:increasing-collisions-in-password-hashing.html</id><summary type="html">&lt;p&gt;With this post I will try to show how, in a theoretical scenario, deliberately
weakening the collision resistance of a password hash function can increase
security. This is by no means a formal proof.&lt;/p&gt;
&lt;p&gt;Suppose Alice has an account on two computer systems &lt;em&gt;X&lt;/em&gt; and &lt;em&gt;Y&lt;/em&gt;. She uses the
same password on both systems.&lt;/p&gt;
&lt;p&gt;Suppose both systems implement the following password hashing scheme: Let &lt;em&gt;t&lt;/em&gt; be
some positive integer. Given a password &lt;em&gt;P&lt;/em&gt;, compute the entropy of the password
&lt;em&gt;H(P)&lt;/em&gt;. Create and store a salted &lt;em&gt;B&lt;/em&gt;-bit hash of &lt;em&gt;P&lt;/em&gt; where &lt;em&gt;B = H(P) - lg(t)&lt;/em&gt;.
To verify a password, wait for &lt;em&gt;t&lt;/em&gt; units of time then check the hash in the
usual manner. Here, the entropy of the password is the logarithm base two of the
number of guesses it will take an adversary to guess the exact password. Also
suppose that it takes one unit of time to compute a hash.&lt;/p&gt;
&lt;p&gt;I claim that using this scheme, Alice's accounts are no less secure than if we
used 256-bit hashes (if &lt;em&gt;H(P) &amp;lt; 256&lt;/em&gt;), and that if System &lt;em&gt;X&lt;/em&gt; gets compromised,
then her account on System &lt;em&gt;Y&lt;/em&gt; is more secure than if we used 256-bit hashes.&lt;/p&gt;
&lt;p&gt;To see why, note two things:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;The probability of any random string &lt;em&gt;S&lt;/em&gt; having the same hash as Alice's
password &lt;em&gt;P&lt;/em&gt; is &lt;em&gt;1/(2^B)&lt;/em&gt;. So if Mallory tries to guess Alice's password
using an online attack, it will take about &lt;em&gt;2^B&lt;/em&gt; guesses, so about &lt;em&gt;2^B * t&lt;/em&gt;
time. So the effective security against an online attack is &lt;em&gt;B + lg(t)&lt;/em&gt;. By
the construction, &lt;em&gt;B + lg(t) = H(P)&lt;/em&gt; so this is no easier than guessing &lt;em&gt;P&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Suppose Mallory roots System &lt;em&gt;X&lt;/em&gt; and gets the &lt;em&gt;B&lt;/em&gt;-bit hash of Alice's
password. It takes Mallory about &lt;em&gt;2^B&lt;/em&gt; guesses to find a preimage. But since
&lt;em&gt;B = H(P) - lg(t)&lt;/em&gt;, Mallory will find about &lt;em&gt;t&lt;/em&gt; collisions when she performs
the same search she would if it was instead a 256-bit hash (this is not at
all a formal argument, but hopefully you see the idea behind it).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;By supposition, Mallory has rooted System &lt;em&gt;X&lt;/em&gt;, so there is no point trying to
secure Alice's account on &lt;em&gt;X&lt;/em&gt; anymore. All that remains is the security of
Alice's account on system &lt;em&gt;Y&lt;/em&gt;. This breaks down if Mallory can get read-only
access to the hash database without rooting... but suppose the root password is
stored in plain text in the hash database ;) .&lt;/p&gt;
&lt;p&gt;Because System &lt;em&gt;Y&lt;/em&gt; is using different salts, it is unlikely that any of the &lt;em&gt;t&lt;/em&gt;
collisions Mallory found, except &lt;em&gt;P&lt;/em&gt; itself, can be used to authenticate as
Alice to System &lt;em&gt;Y&lt;/em&gt; (reader: double check this). So Mallory's best option is to
try authenticating to System &lt;em&gt;Y&lt;/em&gt; as Alice using the &lt;em&gt;t&lt;/em&gt; collisions as passwords
guesses, since she knows &lt;em&gt;P&lt;/em&gt; is one of those &lt;em&gt;t&lt;/em&gt; collisions, and by construction
&lt;em&gt;lg(t) &amp;lt; H(P)&lt;/em&gt;. This will take &lt;em&gt;t * t&lt;/em&gt; time, for an effective security of &lt;em&gt;2
* lg(t)&lt;/em&gt; bits.&lt;/p&gt;
&lt;p&gt;If, instead, System &lt;em&gt;X&lt;/em&gt; was using standard 256-bit hashes, Mallory would have
found the exact &lt;em&gt;P&lt;/em&gt; and could get into System &lt;em&gt;Y&lt;/em&gt; on the first try. Using this
scheme it takes about &lt;em&gt;t&lt;/em&gt; tries. So by weakening the hash, Alice's account on
System &lt;em&gt;Y&lt;/em&gt; is more secure than it would have been had the hash not been
weakened.&lt;/p&gt;
&lt;p&gt;Of course, this system is impractical, since it assumes knowledge of how Mallory
would guess &lt;em&gt;P&lt;/em&gt;, and thus the entropy of &lt;em&gt;P&lt;/em&gt;. It also assumes that if Alice's
hash on System &lt;em&gt;X&lt;/em&gt; gets compromised, then the security of her account on &lt;em&gt;X&lt;/em&gt; no
longer matters at all, which is obviously not always the case. It is
nevertheless interesting to see how the altruism of the compromised system can
increase the security of Alice's account on the other system.&lt;/p&gt;
&lt;p&gt;Another problem is that the user must wait &lt;em&gt;t&lt;/em&gt; units of time when logging in, so
in practice there would be tradeoff between security and log-in wait time.
Locking the accounts after significantly less than &lt;em&gt;t&lt;/em&gt; attempts might be
a better approach.&lt;/p&gt;
&lt;p&gt;It doesn't look like it can be made any better than this, since if you decrease
B any further, finding collisions with an online attack becomes easier than
guessing P, but it is still an online (thus detectable, stoppable) attack so it
might still be harder. I would guess that the wait time &lt;em&gt;t&lt;/em&gt; would be better
spent computing iterations of PBKDF2 or similar.&lt;/p&gt;
</summary><category term="passwords"></category><category term="hashing"></category></entry><entry><title>Why Unsafe State != Deadlock</title><link href="/blog/why-unsafe-state-deadlock.html" rel="alternate"></link><updated>2012-12-10T00:00:00-07:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-12-10:why-unsafe-state-deadlock.html</id><summary type="html">&lt;p&gt;You have a list of processes and a list of resources, and for each process you
have:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The number of each resource they will &lt;em&gt;ever&lt;/em&gt; need at once.&lt;/li&gt;
&lt;li&gt;The number of each resource they are currently allocated.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When a process makes a request for a resource, you only allocate the resource if
allocating the resource does not put the system into an &lt;em&gt;unsafe state&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;What is an unsafe state?&lt;/p&gt;
&lt;p&gt;A system is in a safe state &lt;em&gt;only if&lt;/em&gt; there exists an allocation sequence that
allows the processes to finish executing. Equivalently, if the system is in
a safe state, then there exists an allocation sequence that allows the processes
to finish executing. By contrapositive, if there is no allocation sequence that
allows the processes to finish executing, then the system is in an unsafe state.&lt;/p&gt;
&lt;p&gt;This is &lt;em&gt;not&lt;/em&gt; equivalent to the converse: &amp;quot;If the system is in an unsafe state,
then there is no allocation sequence that allows the processes to finish
executing.&amp;quot;&lt;/p&gt;
&lt;p&gt;So how can a system be in an unsafe state but have an allocation sequence that
allows all processes to finish executing? Remember the assumption that the
banker's algorithm makes: It assumes all processes will request &lt;em&gt;all&lt;/em&gt; resources
they would &lt;em&gt;ever&lt;/em&gt; need at once, then terminate, releasing all of the resources
they just requested and the ones they held. The assumption that can be incorrect
is that processes request &lt;em&gt;all&lt;/em&gt; resources they will ever need. There might not
be an allocation sequence that allows all the processes to finish executing if
they do request &lt;em&gt;all&lt;/em&gt; resources they will ever need, but if the processes
&lt;em&gt;actually don't&lt;/em&gt; request all resources they will ever need (maybe one less, for
example), then it might be enough for the system to avoid getting caught in
a deadlock.&lt;/p&gt;
&lt;p&gt;See the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Banker%27s_algorithm"&gt;Wikipedia article on Banker's Algorithm&lt;/a&gt; for a much better
explanation.&lt;/p&gt;
</summary><category term="threads"></category></entry><entry><title>Gaussian (Gauss-Jordan) Elimination in Ruby</title><link href="/blog/gaussian-elimination-in-ruby.html" rel="alternate"></link><updated>2012-11-11T00:00:00-07:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-11-11:gaussian-elimination-in-ruby.html</id><summary type="html">&lt;p&gt;I had to do some Gaussian elimination for an assignment. So here's Gaussian
elimination in Ruby:&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="c1"&gt;# Performs an in-place Gaussian elimination on an NxN matrix 'matrix' (2D array&lt;/span&gt;
&lt;span class="c1"&gt;# of Numeric objects) and an N-element vector 'vector.' (array of N Numerics).&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;gaussianElimination&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="c1"&gt;# Find the best pivot. This is the one who has the largest absolute value&lt;/span&gt;
    &lt;span class="c1"&gt;# relative to his row (scaled partial pivoting). This step can be omitted&lt;/span&gt;
    &lt;span class="c1"&gt;# to improve speed at the cost of increased error.&lt;/span&gt;
    &lt;span class="n"&gt;maxRelVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;maxIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pivotIdx&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;relVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abs&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;relVal&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;maxRelVal&lt;/span&gt;
        &lt;span class="n"&gt;maxRelVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;relVal&lt;/span&gt;
        &lt;span class="n"&gt;maxIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Swap the best pivot row into place.&lt;/span&gt;
    &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;maxIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;maxIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;maxIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;maxIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

    &lt;span class="n"&gt;pivot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="c1"&gt;# Loop over each row below the pivot row.&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="c1"&gt;# Find factor so that [this row] = [this row] - factor*[pivot row]&lt;/span&gt;
    &lt;span class="c1"&gt;# leaves 0 in the pivot column.&lt;/span&gt;
    &lt;span class="n"&gt;factor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;]/&lt;/span&gt;&lt;span class="n"&gt;pivot&lt;/span&gt;
    &lt;span class="c1"&gt;# We know it will be zero.&lt;/span&gt;
    &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="c1"&gt;# Compute [this row] = [this row] - factor*[pivot row] for the other cols.&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;factor&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;factor&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pivotIdx&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Assumes 'matrix' is in row echelon form.&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;backSubstitution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;downto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Example usage:&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'pp'&lt;/span&gt;

&lt;span class="c1"&gt;# A system of equations: matrix * X = vector&lt;/span&gt;
&lt;span class="n"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Create a backup for verification.&lt;/span&gt;
&lt;span class="n"&gt;matrix_backup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;vector_backup&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dup&lt;/span&gt;

&lt;span class="c1"&gt;# Gaussian elemination to put the system in row echelon form.&lt;/span&gt;
&lt;span class="n"&gt;gaussianElimination&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# Back-substitution to solve the system.&lt;/span&gt;
&lt;span class="n"&gt;backSubstitution&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Print the result.&lt;/span&gt;
&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;
&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;

&lt;span class="c1"&gt;# Verify the result.&lt;/span&gt;
&lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix_backup&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;eqn&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix_backup&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;eqn&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;matrix_backup&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;eqn&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;term&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;vector_backup&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;eqn&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;abs&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mo"&gt;0000000001&lt;/span&gt;
    &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pass&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Verification PASSED.&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Verification FAILED.&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
</summary><category term="gaussian elimination"></category><category term="matrices"></category></entry><entry><title>The Machine that Alters Votes (2012 USA Election)</title><link href="/blog/the-machine-that-alters-votes-2012-usa-election.html" rel="alternate"></link><updated>2012-11-06T00:00:00-07:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-11-06:the-machine-that-alters-votes-2012-usa-election.html</id><summary type="html">&lt;p&gt;So there's &lt;a class="reference external" href="https://www.youtube.com/watch?v=QdpGd74DrBM"&gt;this video&lt;/a&gt; of a voting machine that selects Romney when you try to
click on Obama.&lt;/p&gt;
&lt;p&gt;To someone who has had some experience with touch screen technology, it looks
like the touch system is just out of sync with the UI, which could be fixed by
re-calibrating the system. According to the uploader, it is not a calibration
issue, because they tried tapping other names and they all worked fine. You can
find the uploader's comments in the description of the video. I have no reason
to doubt the uploader's sincerity, since &lt;a class="reference external" href="http://www.motherjones.com/mojo/2012/11/romney-loving-voting-machine-recalibrated-and-back-online"&gt;according to Mother Jones&lt;/a&gt; the
machine was actually taken out of service and &amp;quot;recalibrated.&amp;quot; So the video is
(probably) not fake.&lt;/p&gt;
&lt;p&gt;A lot of people are now assuming this was done intentionally to steal votes from
Obama in favor of Romney. The mainstream media is picking up on the story as
well. The problem with this belief is that if someone did intentionally make the
voting machine behave this way, they could have done something far worse. They
could have made the system swap the votes invisibly, behind-the-scenes, so that
nobody ever notices.&lt;/p&gt;
&lt;p&gt;If it was done intentionally, and whoever did it could have made the machine
swap votes invisibly, then you have to ask the question: Why did they make it
visible? Certainly if a &lt;em&gt;lot&lt;/em&gt; of these machines started doing what is seen in
the video, a lot of people would notice, and it would be clear that there was
some kind of fraud was going on. The election results would clearly be invalid.
A lot of vote-altering machines would invalidate the election, but just one is
enough to make everyone panic and to get the story covered by the popular news
media, giving Romney some potentially bad publicity. So a possibly better
explanation, if it was intentional, is that it was done by a supporter of one of
the &lt;em&gt;other&lt;/em&gt; candidates.&lt;/p&gt;
&lt;p&gt;Or, it could just be a bug. I think it is.&lt;/p&gt;
</summary><category term="voting"></category></entry><entry><title>Coders, PLEASE STOP inventing your own hash functions!</title><link href="/blog/coders-please-stop-inventing-your-own-hash-functions.html" rel="alternate"></link><updated>2012-08-21T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-08-21:coders-please-stop-inventing-your-own-hash-functions.html</id><summary type="html">&lt;p&gt;Today, I came across an &lt;a class="reference external" href="&amp;quot;http://arstechnica.com/security/2012/08/passwords-under-assault/"&gt;article on password cracking&lt;/a&gt;. In the comment section
I saw someone had posted (presumably right after they just read about salting)
the following reply:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
My solution: don't store hashes as a single SHA1 or MD5 result ...
combine it for further obfuscation. A hash is designed to fall into
enemy hands, so don't make it easy to produce rainbow tables.

SAMPLE - All other password weaknesses still apply!

function generateHash($name, $pass)
{
$salt = '';
for($i = 0; $i &amp;lt; strlen($name); $i++) { $salt = $i . $salt . $name . $i; }
return (sha1($salt . $pass) . sha1($pass . $name . $salt));
}
&lt;/pre&gt;
&lt;p&gt;This code is exactly as secure as &lt;tt class="docutils literal"&gt;sha1( $name . $pass );&lt;/tt&gt;. It does not make
it harder to produce rainbow tables, it is &lt;a class="reference external" href="https://defuse.ca/blog/what-is-security-through-obscurity.html"&gt;security through obscurity&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I come across an example like this almost ever week. Please stop inventing your
own hash functions and use a &lt;a class="reference external" href="https://crackstation.net/hashing-security.htm"&gt;standard salted and iterated key derivation
function&lt;/a&gt;.&lt;/p&gt;
</summary><category term="passwords"></category><category term="hashing"></category></entry><entry><title>x86 Stack Diagrams</title><link href="/blog/x86-stack-diagrams.html" rel="alternate"></link><updated>2012-08-14T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-08-14:x86-stack-diagrams.html</id><summary type="html">&lt;p&gt;All of the x86 stack diagrams I could find are either cluttered with too much
information, can't be read from a distance, or put the high address on top (I'm
sure there are people who prefer that but... I'm not one of them). So I made my
own.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;With low address on top (stack growing up, strcpy going down):&lt;/strong&gt;&lt;/p&gt;
&lt;img alt="x86 Stack with low addresses on top" src="https://defuse.ca/images/stack-low-high.gif" /&gt;
&lt;p&gt;&lt;strong&gt;With high address on top (stack growing down, strcpy going up):&lt;/strong&gt;&lt;/p&gt;
&lt;img alt="x86 Stack with high addresses on top" src="https://defuse.ca/images/stack-high-low.gif" /&gt;
</summary><category term="x86"></category><category term="assembly"></category></entry><entry><title>Recovering CBC-mode IV via Chosen Ciphertext</title><link href="/blog/recovering-cbc-mode-iv-chosen-ciphertext.html" rel="alternate"></link><updated>2012-08-12T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-08-12:recovering-cbc-mode-iv-chosen-ciphertext.html</id><summary type="html">&lt;p&gt;Suppose a system uses a constant internal initialization vector to
encrypt/decrypt data in CBC mode, and you'd like to know what it is. If you can
make the system decrypt chosen ciphertexts, this is how you do it:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Make the system decrypt two equal blocks of ciphertext (e.g. all zeroes).&lt;/li&gt;
&lt;li&gt;XOR the two resulting blocks of &amp;quot;plaintext&amp;quot; together.&lt;/li&gt;
&lt;li&gt;XOR that with the original ciphertext block.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Visually:&lt;/p&gt;
&lt;img alt="Recovering IV with chosen ciphertext" src="https://defuse.ca/images/iv-recovery.gif" /&gt;
&lt;p&gt;The best I can think of for recovering a static IV under chosen plaintext is
a meet-in-the-middle attack as follows.&lt;/p&gt;
&lt;p&gt;Observation 1: We can specify input directly to the cipher by:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Encrypt a one-block plaintext X, getting the resulting ciphertext C.&lt;/li&gt;
&lt;li&gt;Encrypt the two-block plaintext X||(Y xor C), where Y is the block we want to
feed directly into the cipher.&lt;/li&gt;
&lt;li&gt;The second block of ciphertext will be the result of feeding Y directly into
the cipher.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Observation 2: We can encrypt the IV itself and variations of it by varying the
first block of plaintext. Formally C = E(V xor IV), when V is the first block of
plaintext. We'll call V a &amp;quot;variation vector.&amp;quot;&lt;/p&gt;
&lt;p&gt;So,&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Create a lookup table mapping 2^64 (assuming the block size is 128 bits)
random variation vectors &lt;em&gt;from&lt;/em&gt; the resulting ciphertext. This lets us look
up what variation we made to the IV to result in a given ciphertext block.&lt;/li&gt;
&lt;li&gt;Use the method in observation 1 to encrypt random blocks fed directly into
the cipher. Look up each ciphertext in the table from step (1). If it's
there, then the IV is &amp;lt;the block that was fed directly into the cipher&amp;gt; XOR
&amp;lt;the variation vector&amp;gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The lookup table from step (1) gives us a 1 in 2^64 chance of finding the IV per
known plaintext-ciphertext pair. So it should take about 2^64 iterations in step
(2) before we recover the IV.&lt;/p&gt;
</summary><category term="cryptography"></category></entry><entry><title>Visual Basic's "With" in Ruby</title><link href="/blog/visual-basic-with-in-ruby.html" rel="alternate"></link><updated>2012-08-04T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-08-04:visual-basic-with-in-ruby.html</id><summary type="html">&lt;pre class="code ruby literal-block"&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="no"&gt;Math&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Deeply nested modules&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Foo&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Bar&lt;/span&gt;

    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Baz&lt;/span&gt;
      &lt;span class="no"&gt;A_CONSTANT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="no"&gt;A_CONSTANT&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;A_CONSTANT&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Biz&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;anotherMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;hello &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="ss"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Bar&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="ss"&gt;m&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Baz&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;aMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="ss"&gt;m&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="ss"&gt;:Biz&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;anotherMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;bob&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
</summary><category term="basic"></category></entry><entry><title>Raspberry PI: Enable MPlayer and VLC audio on Raspbian</title><link href="/blog/raspberry-pi-enable-mplayer-and-vlc-audio-on-rasbian.html" rel="alternate"></link><updated>2012-08-02T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-08-02:raspberry-pi-enable-mplayer-and-vlc-audio-on-rasbian.html</id><summary type="html">&lt;!-- NOTE: The slug misspells raspbian intentionally so it matches the old URL. --&gt;
&lt;p&gt;If mplayer is giving you an error like the following...&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
AO: [pulse] Init failed: Connection refused
Failed to initialize audio driver 'pulse'
[AO_ALSA] Unable to set hw-parameters: Invalid argument
Failed to initialize audio driver 'alsa'
[AO SDL] Samplerate: 44100Hz Channels: Stereo Format floatle
[AO SDL] using aalib audio driver.
[AO SDL] Unsupported audio format: 0x1d.
[AO SDL] Unable to open audio: No available audio device
Failed to initialize audio driver 'sdl:aalib'
Could not open/initialize audio device -&amp;gt; no sound.
Audio: no sound
Video: no video
&lt;/pre&gt;
&lt;p&gt;... add the following to /etc/asound.conf (create it if it does not exist):&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
pcm.!default {
    type hw
    card 0
}

ctl.!default {
    type hw
    card 0
}
&lt;/pre&gt;
&lt;p&gt;Then, run:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
modprobe snd_bcm2835
&lt;/pre&gt;
&lt;p&gt;Then add the following &lt;tt class="docutils literal"&gt;/etc/modules&lt;/tt&gt; (unless it's already there):&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
snd-bcm2835
&lt;/pre&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.raspberrypi.org/phpBB3/viewtopic.php?f=66&amp;amp;t=7107"&gt;Source - &amp;quot;ALSA on Raspbian&amp;quot;&lt;/a&gt;.&lt;/p&gt;
</summary><category term="raspberry pi"></category><category term="raspbian"></category></entry><entry><title>Linux: Fix pipe character on ASUS laptops</title><link href="/blog/linux-fix-pipe-character-on-asus-laptops.html" rel="alternate"></link><updated>2012-07-27T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-07-27:linux-fix-pipe-character-on-asus-laptops.html</id><summary type="html">&lt;p&gt;Is your pipe/backslash key not typing pipes and backslashes? Is it typing
less-than and greater-than symbols? If so, add...&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
key &amp;lt;LSGT&amp;gt; { [ backslash, bar, backslash, bar] };
&lt;/pre&gt;
&lt;p&gt;..to &lt;cite&gt;/usr/share/X11/xkb/symbols/us&lt;/cite&gt; in the &lt;cite&gt;kxb_symbols&lt;/cite&gt; &lt;cite&gt;&amp;quot;basic&amp;quot;&lt;/cite&gt; section.&lt;/p&gt;
&lt;p&gt;This seems to be a problem with ASUS laptops, I've seen two of them doing this.&lt;/p&gt;
&lt;p&gt;Reference: &lt;a class="reference external" href="http://forums.fedoraforum.org/showthread.php?t=240415"&gt;http://forums.fedoraforum.org/showthread.php?t=240415&lt;/a&gt;&lt;/p&gt;
</summary><category term="keyboard"></category></entry><entry><title>How to install mod_ruby on Debian Squeeze</title><link href="/blog/how-to-install-mod_ruby-on-debian-squeeze.html" rel="alternate"></link><updated>2012-07-22T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-07-22:how-to-install-mod_ruby-on-debian-squeeze.html</id><summary type="html">&lt;p&gt;If you're a PHP developer that's starting to fall in love with ruby (like me),
you'll want to know how to write &amp;quot;PHP-style&amp;quot; web applications in ruby, for small
web apps that don't need the complexity of Ruby on Rails. You want:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;No per-app configuration necessary. Installing the app is as simple as
uploading the script files.&lt;/li&gt;
&lt;li&gt;Each ruby file you upload is an independent web page, e.g.
&lt;a class="reference external" href="http://example.com/foo.rhtml"&gt;http://example.com/foo.rhtml&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Scripts are HTML with ruby code inside delimiters (like php's &amp;lt;?php and ?&amp;gt;).&lt;/li&gt;
&lt;li&gt;Scripts have easy access to GET and POST data, as well as HTTP headers and
cookies.&lt;/li&gt;
&lt;li&gt;Scripts can easily send headers, set cookies, etc.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Unfortunately, to get this working on Debian Squeeze, some initial configuration
required, but it's a one time thing and quick in comparison to the per-app
configuration required by RoR.&lt;/p&gt;
&lt;p&gt;First, install mod_ruby:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
apt-get install libapache2-mod-ruby
&lt;/pre&gt;
&lt;p&gt;Second, add the following to your site's configuration and read the embedded
comments. Note that in order to lower the ruby safe level with the RubySafeLevel
directive (default is 1), it must appear &lt;strong&gt;outside any &amp;quot;files&amp;quot;, &amp;quot;directory&amp;quot;, and
&amp;quot;virtualhost&amp;quot; blocks.&lt;/strong&gt; If not, you will get an error like: &lt;tt class="docutils literal"&gt;mod_ruby: can't
decrease RubySafeLevel&lt;/tt&gt;.&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
&amp;lt;IfModule mod_ruby.c&amp;gt;
    RubyRequire apache/ruby-run
    RubyRequire apache/eruby-run

    # Safe level 1 does taint checking, but also won't let you run .rb scripts
    # from a world-writable folder. I highly recommend keeping this at 1, but
    # in a development environment, you can change it to 0 to make scripts
    # run from world-writable folders (OTOH, you really DO want to develop with
    # taint checking turned on).
    RubySafeLevel 1

    # Override the mime types in /etc/mime.types so the output of the script
    # is displayed in the browser, not sent as a download. Some guides will
    # tell you to comment out the corresponding entries in /etc/mime.types, but
    # don't do that as it will affect the entire system, not just apache.
    AddType text/html .rb
    AddType text/html .rbx
    AddType text/html .rhtml

    # NOTE: To make .rb files execute, you will need to add:
    #  Options +ExecCGI
    # to the &amp;lt;Directory&amp;gt; they are in. You DON'T need to do this for .rhtml.
    &amp;lt;Files *.rb&amp;gt;
        SetHandler ruby-object
        RubyHandler Apache::RubyRun.instance
    &amp;lt;/Files&amp;gt;
    &amp;lt;Files *.rbx&amp;gt;
        SetHandler ruby-object
        RubyHandler Apache::RubyRun.instance
    &amp;lt;/Files&amp;gt;
    &amp;lt;Files *.rhtml&amp;gt;
        SetHandler ruby-object
        RubyHandler Apache::ERubyRun.instance
    &amp;lt;/Files&amp;gt;
&amp;lt;/IfModule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now, .rhtml files will work like PHP files:&lt;/p&gt;
&lt;pre class="code erb literal-block"&gt;
&lt;span class="x"&gt;&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Hello, world!&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    Even numbers less than 100:
    &amp;lt;ul&amp;gt;
    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt;
      &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;
    &amp;lt;/ul&amp;gt;
    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt;
      &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;
      This text repeats &amp;lt;b&amp;gt;50&amp;lt;/b&amp;gt; times! &amp;lt;br /&amp;gt;
    &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;And .rb files will work like CGIs:&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="c1"&gt;#!/usr/bin/ruby&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;ul&amp;gt;&amp;quot;&lt;/span&gt;
&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;li&amp;gt;Some text!&amp;lt;/li&amp;gt;&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;/ul&amp;gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;In both types of script, you can use &lt;a class="reference external" href="http://modruby.net/en/doc/?Apache%3A%3ARequest"&gt;Apache.request&lt;/a&gt; to read GET and POST
data, set cookies, etc.&lt;/p&gt;
&lt;pre class="code erb literal-block"&gt;
&lt;span class="x"&gt;&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Hello, world!&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
   GET data in rhtml mod_ruby!
   &lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt;
   &lt;span class="no"&gt;Apache&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;paramtable&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'count'&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;to_i&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
     &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
   &lt;span class="k"&gt;end&lt;/span&gt;
   &lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;div class="section" id="why"&gt;
&lt;h2&gt;Why?&lt;/h2&gt;
&lt;p&gt;Writing this post made me realize I'm trying to make ruby do something it
doesn't (yet) do well. PHP has so many built-in features for doing web stuff
like htmlentities, built-in mysql access, and easy access to GET and POST data
through $_GET and $_POST (note that Apache.request.paramtable includes both GET
and POST data, which is bad for security), so for now, I think I'll stick with
PHP until there's a better zero-config lightweight ruby web framework. Sinatra
is the best I have seen so far, but configuring it with Apache is still far too
complicated, in my opinion.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="mod_ruby"></category></entry><entry><title>Escaping String Literals (for JavaScript) in PHP</title><link href="/blog/escaping-string-literals-for-javascript-in-php.html" rel="alternate"></link><updated>2012-07-01T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-07-01:escaping-string-literals-for-javascript-in-php.html</id><summary type="html">&lt;p&gt;Use the following code to escape user-supplied input before inserting it into
a JavaScript string literal.&lt;/p&gt;
&lt;pre class="code php literal-block"&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;js_string_escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$safe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ctype_alnum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
            &lt;span class="nv"&gt;$safe&lt;/span&gt; &lt;span class="o"&gt;.=&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="nv"&gt;$safe&lt;/span&gt; &lt;span class="o"&gt;.=&lt;/span&gt; &lt;span class="nb"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;x%02X&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;ord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$safe&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre class="code php literal-block"&gt;
&lt;span class="x"&gt;&amp;lt;script&amp;gt;
var foo = &amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nx"&gt;js_string_escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$bar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&amp;quot;;
&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The standard htmlentities and htmlspecialchars functions don't work because
JavaScript will interpret the HTML entities as a part of the literal string (not
decode them). addslashes is insufficient because it does not escape other
special characters that might convince some browsers that the string literal or
script section has ended (for example, the string &amp;quot;]]&amp;gt;&amp;quot; to end a &lt;a class="reference external" href="http://www.w3schools.com/xml/xml_cdata.asp"&gt;CDATA&lt;/a&gt;). To
escape integers and floats, use these:&lt;/p&gt;
&lt;pre class="code php literal-block"&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;// returns &amp;quot;0&amp;quot; when given something that isn't an integer.
&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;js_integer_escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$cast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cast&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$cast&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;pre class="code php literal-block"&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="c1"&gt;// returns &amp;quot;0&amp;quot; when given something that isn't a float
&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;js_float_escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;is_float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;is_numeric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$number&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;0&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;$number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;
</summary><category term="javascript"></category><category term="escaping"></category></entry><entry><title>Using 'wmctrl' to Quickly Switch Between Open Applications</title><link href="/blog/wmctrl-switch-applications-keyboard-shortcut.html" rel="alternate"></link><updated>2012-06-23T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-06-23:wmctrl-switch-applications-keyboard-shortcut.html</id><summary type="html">&lt;p&gt;The &lt;tt class="docutils literal"&gt;wmctrl&lt;/tt&gt; program allows you to programatically bring a running application
to the foreground on Linux. It works even with compiz enabled, and will switch
to the virtual desktop that the application is running in before bringing it to
the foreground. This makes it a perfect utility for mapping keyboard shortcuts
to quickly switch between applications you leave running all the time.&lt;/p&gt;
&lt;p&gt;To install wmctrl on Debian:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
apt-get install wmctrl
&lt;/pre&gt;
&lt;p&gt;For example, to switch to Thunderbird:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
wmctrl -a &lt;span class="s2"&gt;&amp;quot;Mozilla Thunderbird&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-a&lt;/span&gt;&lt;/tt&gt; argument makes wmctrl switch to the first window it finds with the
provided string in its title. See wmctrl's manpage for more information.&lt;/p&gt;
&lt;p&gt;You can map a command like this to a keyboard shortcut using the (in Debian)
&lt;tt class="docutils literal"&gt;System &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Preferences &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Keyboard Shortcuts&lt;/tt&gt; utility.&lt;/p&gt;
</summary><category term="wmctrl"></category></entry><entry><title>Disable 'locate' Command Index Databases</title><link href="/blog/disable-locate-command-databases.html" rel="alternate"></link><updated>2012-06-20T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-06-20:disable-locate-command-databases.html</id><summary type="html">&lt;p&gt;If you use Truecrypt on GNU/Linux, you will want to stop mlocate (the locate
command) from automatically indexing your files and compromising your privacy.&lt;/p&gt;
&lt;p&gt;To do so on Debian Squeeze:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
apt-get remove mlocate rm /etc/cron.daily/mlocate
&lt;/pre&gt;
&lt;p&gt;The database files are stored in:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
/var/lib/mlocate/
&lt;/pre&gt;
&lt;p&gt;Delete them with your secure-delete utility of choice.&lt;/p&gt;
</summary><category term="locate"></category></entry><entry><title>Awesome Desktop Calculator using Ruby's IRB</title><link href="/blog/awesome-desktop-calculator-using-rubys-irb.html" rel="alternate"></link><updated>2012-06-09T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-06-09:awesome-desktop-calculator-using-rubys-irb.html</id><summary type="html">&lt;p&gt;Ruby is an awesome programming language. Its metaprogramming capabilities make
it easy to turn the interactive ruby interpreter (irb) into an awesome desktop
calculator. To do so, we can make irb execute a ruby script, containing some
calculator extensions before it starts, with the following command:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
irb -r /path/to/the/file.rb
&lt;/pre&gt;
&lt;p&gt;Of course, you will want to make an alias or keyboard shortcut for this. In
bash, this can be done by adding something like the following to ~/.bashrc:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;rcalc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'irb -r /path/to/the/file.rb'&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Here's a link to my &lt;a class="reference external" href="https://defuse.ca/source/calc.rb"&gt;custom ruby calculator script&lt;/a&gt;. Here's what it does:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
+----------------------------- RUBY CALCULATOR -------------------------------+
|  0b - Binary    .b - To Binary      Constants: E, PI                        |
|  0x - Hex       .h - To Hex         _ gives last result                     |
|  0  - Octal     .o - To Octal       q quits                                 |
+-----------------------------------------------------------------------------+
|  Window closes after 10 minutes of inactivity. Type 'keepalive' to disable. |
+-----------------------------------------------------------------------------+
irb(main):001:0&amp;gt; 0b11111111
=&amp;gt; 255
irb(main):002:0&amp;gt; _.h
=&amp;gt; &amp;quot;ff&amp;quot;
irb(main):003:0&amp;gt; PI
=&amp;gt; 3.14159265358979
irb(main):004:0&amp;gt; E
=&amp;gt; 2.71828182845905
irb(main):005:0&amp;gt; 2**256 / 3**5
WARNING: Integer division with remainder.
=&amp;gt; 476510655297597512031156316908180690754197467759837712096533267522276253662
irb(main):006:0&amp;gt; 6/3
=&amp;gt; 2
irb(main):007:0&amp;gt; 5.0/2
=&amp;gt; 2.5
irb(main):012:0&amp;gt; sin(PI/2)
=&amp;gt; 1.0
irb(main):008:0&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I will be adding functionality to this script as I need it. Some things I'm
planning are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Unit conversions&lt;/li&gt;
&lt;li&gt;Easier way to convert strings in different bases to integers&lt;/li&gt;
&lt;li&gt;Efficient factorial function&lt;/li&gt;
&lt;li&gt;Common sequences such as Fibonacci&lt;/li&gt;
&lt;li&gt;Common formulas&lt;/li&gt;
&lt;li&gt;Common constants (c, G, etc.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you have any ideas, please leave a comment and I'll add it to the list.&lt;/p&gt;
</summary><category term="calculator"></category></entry><entry><title>Cracking eHarmony's Unsalted Hashes with CrackStation</title><link href="/blog/cracking-eharmonys-unsalted-hashes-with-crackstation.html" rel="alternate"></link><updated>2012-06-09T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-06-09:cracking-eharmonys-unsalted-hashes-with-crackstation.html</id><summary type="html">&lt;p&gt;This week, LinkedIn, eHarmony, and last.fm have all confirmed that their
password hash databases have been breached. In all three cases, passwords were
stored as an unsalted hash. I've already reported the &lt;a class="reference external" href="https://defuse.ca/blog/cracking-linkedin-hashes-with-crackstation.html"&gt;results of cracking
LinkedIn's password hashes with CrackStation&lt;/a&gt;, now it's eHarmony's turn.&lt;/p&gt;
&lt;p&gt;eHarmony stored their users' passwords as an unsalted md5 hash. The leaked file
contains 1,516,877 hashes. You can download the original file from one of either
of the following links:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://defuse.ca/files/eharmony-hashes.txt"&gt;eHarmony Hashes HTTP Mirror&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://thepiratebay.se/torrent/7341755/eHarmony_Unsalted_MD5_Hash_Database"&gt;eHarmony Hashes TORRENT Mirror&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are no repeated hashes in the file, so presumably the party that leaked
them removed the duplicates. Because there are no duplicates, I can't provide
any &amp;quot;most common passwords&amp;quot; statistics, but I can report how many
&lt;a class="reference external" href="https://crackstation.net/"&gt;CrackStation&lt;/a&gt; was able to crack, and how fast it did so.&lt;/p&gt;
&lt;p&gt;The cracking process took 23.47 hours and recovered 275,860 (18.2%) of the
passwords. CrackStation processed the hashes at an average rate of 17.94 hashes
per second. All passwords are upper case, so I suspect that eHarmony was
converting passwords to upper case before hashing them to implement case
insensitivity (another big no-no).&lt;/p&gt;
&lt;p&gt;CrackStation uses two dictionaries. One, which I call the &amp;quot;medium&amp;quot; dictionary,
has 1,493,677,782 entries. The other, which I call the &amp;quot;huge&amp;quot; dictionary, has
15,171,326,912 entries. 250,122 of the cracked passwords are present in the
&amp;quot;medium&amp;quot; dictionary, 97,419 are in the &amp;quot;huge&amp;quot; dictionary, and 71,380 passwords
are in both.&lt;/p&gt;
&lt;p&gt;If eHarmony had &lt;a class="reference external" href="https://crackstation.net/hashing-security.htm"&gt;used salt in their hashes&lt;/a&gt; like they should have been,
I wouldn't have been able to run this attack. In fact, salting would have forced
me to run a dictionary attack on each hash by itself, and that would have taken
me over 31 years.&lt;/p&gt;
&lt;p&gt;I'm very glad the LinkedIn, eHarmony, and last.fm breaches all went public at
nearly the same time. The stories are have been covered by nearly every tech
news website, and the issue of inadequate server-side password protection is
finally being addressed. I hope other companies will learn from these breaches
and start using salted hashes if they aren't already doing so.&lt;/p&gt;
&lt;p&gt;Unsalted hashes are bad, but storing passwords in plain-text is even worse.
Visit my &lt;a class="reference external" href="https://defuse.ca/password-policy-hall-of-shame.htm"&gt;Password Policy Hall of Shame&lt;/a&gt; for a list of websites that are
probably storing your password in the clear.&lt;/p&gt;
&lt;p&gt;You probably came here wanting to see passwords, so I won't disappoint. Here's
a random sample:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
39007e310acd5cc5582c34c408ebf4cc :: RAWANN
c69f24b431852eb5b2db419860387dad :: SHELDURAY88
713f6fcbeeacbd3a78401382f88f5d1f :: KJ1017
86fc184cabcf0626c479927cc4e5e998 :: PUSSY310
c075be959b6831fb01d52591963d12b7 :: KARAAGE4
6c058fea843d5bff058c939fde3a6eb8 :: TH3EMPRESS
2dfecece2bf00698dd5fbae90e2f0860 :: ELLEGRA
e720578393bb68956f079c3db426d6ec :: 81PIRTER73
b0963f1a7fd94698a6e76e402daffcef :: KORRESHI
026d29ad37c6c672315e5a9c358d0a7c :: CLC47
7d01d8893e7ddbb18ceb40c59ef384c2 :: ROMELP
bf1a688689f82ba39b9efa236d09c539 :: OFTROY
dfcd9ad16c5358c1c420343a7b2b683b :: MVN2006
14f6609d95e3830b14709bce165041af :: MIKYONE
2b1841891df6de05b163d8dbbe79036c :: JAMFILE
9fe44d8eb7fbc5217fad2e54d09871ed :: TRIATA
961887ee6a084c02619f22f6b2e8a852 :: IAMTHATIS
fd9d9fa433c0d9385345355c17be13f4 :: PEACHKA1
fa22376fe0782fe9313385846e66b979 :: JAHAAD
095614e5971ad8a81d4f232c00bbf33d :: SARAHMIA1
f14c92dd1b2281cdf0f5999e595442de :: LEBIN
6e0f9ff4606b41705ea25bcbff1ac94b :: WINGK2
49cacc76a288058b68ded69f0c804269 :: CHARLIEXX
cbc7f37615111efe8e246d3316e24408 :: MB1229
81fc99cc34d28eec3c90109cab7ddfbe :: EMETI
e838f7db8ef56faa9b49e8215dfbbee7 :: KITABLAR
02ae65a2f3dac98a54290f09c39758ed :: JENGARY
3a7edcb86afee6b0853fba0a16672bcd :: GODSPELL2
22d541659b917e40146f4d4256b2a2e2 :: LETSTALK2
4e953e9a0a0f2503e8b8269b2c4a8057 :: 1MEMO1
&lt;/pre&gt;
</summary><category term="passwords"></category><category term="hashing"></category><category term="eharmony"></category></entry><entry><title>Cracking LinkedIn's Hashes with Crackstation</title><link href="/blog/cracking-linkedin-hashes-with-crackstation.html" rel="alternate"></link><updated>2012-06-08T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-06-08:cracking-linkedin-hashes-with-crackstation.html</id><summary type="html">&lt;p&gt;&lt;a class="reference external" href="http://linkedin.com/"&gt;LinkedIn&lt;/a&gt;'s user database has been &lt;a class="reference external" href="https://news.ycombinator.com/item?id=4073309"&gt;breached&lt;/a&gt;. The passwords were hashed with
SHA1, but salt was not used. 6 million of them have been published to the
internet. You can download them via &lt;a class="reference external" href="http://thepiratebay.se/torrent/7334648/LinkedIn_Password_Hashes"&gt;torrent&lt;/a&gt; or via HTTP from &lt;a class="reference external" href="http://defuse.ca/files/linkedin-sha1.txt"&gt;defuse.ca's
mirror&lt;/a&gt;. 3.5 million of them have had their first 5 hex digits replaced with
zero -- some suspect this was used as a way to mark which have been cracked by
another party &lt;a class="reference external" href="https://news.ycombinator.com/item?id=4073928"&gt;(source)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A bit of googling reveals that LinkedIn has about 120 million registered
accounts, so the 6,143,150 hashes represent about 5% of LinkedIn users
Correction: Since duplicates were removed from the hash list, it must represent
a much larger portion of LinkedIn users. Since passwords are so often re-used,
I wouldn't be surprised if it was the entire database. 3,521,180 have been
cracked by an unknown third party. That leaves 2,621,970 for me to try to crack
with &lt;a class="reference external" href="https://crackstation.net/"&gt;CrackStation&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="what-is-crackstation"&gt;
&lt;h2&gt;What is CrackStation?&lt;/h2&gt;
&lt;p&gt;CrackStation is basically a giant lookup table -- a sorted list of hashes,
mapped to their corresponding plaintext. To crack a hash, all I have to do is
run a binary search through the hash index file to get the location of the
plaintext in the wordlist file. This process is very efficient; a 200GB index
file (15 billion hashes) can be searched in only a fraction of a second, even on
a standard 7200rpm hard disk.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="crackstation-results"&gt;
&lt;h2&gt;CrackStation Results&lt;/h2&gt;
&lt;p&gt;It took 31.8 hours to process all 2,621,970 not-yet-cracked hashes. That's an
average of 22 hashes processed per second. In the end, I was able to crack
31,831 hashes -- about 1.2%. CrackStation's &amp;quot;medium&amp;quot; dictionary, which has
1,493,677,782 entries, cracked 23,529 (0.8%) of them. The &amp;quot;huge&amp;quot; dictionary,
which has 15,171,326,912 cracked 10034 (0.3%) of them. These figures are not
exclusive -- 1732 hashes were cracked by both dictionaries (I did not optimize).&lt;/p&gt;
&lt;p&gt;Duplicates were removed from the original list of hashes, so I cannot provide
&amp;quot;most common passwords&amp;quot; statistics. Here's a random sample of what I cracked (I
will not be releasing the full list):&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
6764dcf2d9c84b9d66fd5c8a78691affde1045e1 :: sangeetalahiri
d6b3ebab49bd83a60de4f5b84d9fe61eff5cba73 :: DualPhone
c79b146f16d3442bb2adb00cf9a6e456aacdb877 :: juan.rondon
777bb3743c7424b477ae95f0b002cffc3a6d8f57 :: Charlcombe1
a567e183044b8a881a8aec41387614f7963b60be :: hydroworx1
7f97cd544c2937e494265a6a5a4ae3edf6a391e8 :: Jetravaille
87f11d9ccda89e463cf92e3f84dbf1f5b9b5f84a :: Nangiya1
1168caf06e26fb82642b069dc306b9a849e9448f :: kab&amp;#64;las
3722fd3f3cded4dc1231df6b16190364eaf71184 :: grasmachien
5a61c766bb6ea7294a6a0e6e2ccbda8c4eed0ebc :: Eidner4
&lt;/pre&gt;
&lt;p&gt;These results aren't really meaningful, since I only tried to crack the set of
hashes that were not already cracked by someone else, but it was a fun exercise
to test the strength of CrackStation's password dictionaries. It is also a great
demonstration of why salt is &lt;strong&gt;crucial&lt;/strong&gt; to password security. If we assume that
all of the previously-cracked hashes could have been cracked by CrackStation,
then I would have been able to crack 3,553,011 (57.8%) in only 78 hours, or 19
hours if cracked them in parallel on a quad-disk quad-core system. That figure
is consistent with other bulk cracking jobs CrackStation has done in the past.&lt;/p&gt;
&lt;p&gt;The reason I cannot crack the ones that had their first 5 hex digits set to
00000 is because CrackStation's indexes are sorted on the first 48 bits of the
hash, with the first bits being the most significant. Without all of those bits,
I can't do a binary search through the index file. I could rebuild the index
using the last 48 bits of the hash, but that would take days and hundreds of
gigabytes of hard drive space. I don't want LinkedIn users' passwords that bad.
If there is significant public interest in the results, then I will consider
doing it.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This kind of attack wouldn't work if the hashes were salted. If they were
salted, I'd have to run a dictionary attack on each hash individually, which can
take upwards of an hour per hash for a similar-quality attack. So if you run
a website that stores user passwords, please make sure they are &lt;a class="reference external" href="https://crackstation.net/hashing-security.htm"&gt;hashed with
salt&lt;/a&gt;. If they aren't, (LinkedIn, are you listening?), then you are an
irresponsible webmaster.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="passwords"></category><category term="hashing"></category><category term="linkedin"></category></entry><entry><title>What is Security Through Obscurity</title><link href="/blog/what-is-security-through-obscurity.html" rel="alternate"></link><updated>2012-06-04T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-06-04:what-is-security-through-obscurity.html</id><summary type="html">&lt;p&gt;Today a member of &lt;a class="reference external" href="https://www.grc.com/discussions.htm"&gt;GRC's Newsgroups&lt;/a&gt; posed a question about security through
obscurity:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It seems to me that ALL digital security is EXACTLY &amp;quot;security through
obscurity&amp;quot;. Take, for example, AES... It isn't that the possible range of
keys is unknown, it is just a cleverly hidden needle in an enormously HUGE
haystack.  It could actually be possible to arrive at the correct key on the
first guess.  However, I wouldn't bet anything you care about on that, since
it would be about as likely as me saying, &amp;quot;I'm thinking of a particular atom
somewhere in the universe. Can you guess which one?&amp;quot; Nevertheless, in set
notation, it would be trivial to describe the set which includes the correct
key. It is simply obscured by all the wrong keys.&lt;/p&gt;
&lt;p&gt;So, by your definition, what is &lt;em&gt;real&lt;/em&gt; security?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It's a very interesting question, and it made me realize that in all of the
research I've done on cryptography, I've never seen a formal definition of
security through obscurity. It took me a while to come up with a reasonable
response (something other than &amp;quot;I know it when I see it.&amp;quot;). My first thought was
anything that doesn't follow &lt;cite&gt;Kerckhoffs's principle&lt;/cite&gt; is security through
obscurity, but I wanted something more general. After a bit more thinking,
I decided that measurability is the main distinction between something that
isn't security through obscurity, and something that is. Here's what I wrote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Informally, I would define security, with respect to cryptography, as
something that requires a well-defined and measurable amount of resources to
break in a specific scenario.&lt;/p&gt;
&lt;p&gt;For example, if a message is encrypted in AES-256 in CBC mode, with a random
key, and the adversary knows the plaintext is english, but doesn't know
anything about the key, then the security factor is 2^256 i.e. the adversary
has to do on average 2^255 operations to successfully decrypt the
ciphertext.&lt;/p&gt;
&lt;p&gt;Note that this means that even if the key is just one bit, it is still
&amp;quot;real&amp;quot; security, as long as the adversary knows that the key is either &amp;quot;1&amp;quot;
or &amp;quot;0&amp;quot;. It is very weak security, but the difficulty of cracking it is still
well-defined and computable.&lt;/p&gt;
&lt;p&gt;Security though obscurity is anything that doesn't have a well-defined and
computable &amp;quot;security factor&amp;quot; in at least one scenario.&lt;/p&gt;
&lt;p&gt;For example, if you are trying to smuggle pirated software across the U.S.
border, you may choose to encode the data into the least significant bits of
the RGB values in an image file. There is software for doing (and un-doing)
this, so it would not be hard for the border patrol officer to extract the
data, if he knew it was there. Your security rests on whether or not the
officer will know to look in the least significant bits for hidden data.
This is not well-defined and cannot be computed into a &amp;quot;security factor&amp;quot;
like above.&lt;/p&gt;
&lt;p&gt;A real-world example is if you just won the lottery and you are looking for
a place to hide your money (supposing banks don't exist):&lt;/p&gt;
&lt;p&gt;You could choose to buy a safe, rated to withstand 60 minutes of attack with
blow torches. This is &amp;quot;real&amp;quot; security, the amount of work an adversary has
to do to break into the safe is well-defined and computable.&lt;/p&gt;
&lt;p&gt;You could also choose to hide your money inside the door of your car
(between the interior panel and the exterior metal). It would not be at all
difficult for an adversary to steal your money, if they knew it was there.
The security provided by &amp;quot;Will the adversary ever think that I am hiding the
money in the door of my car?&amp;quot; is not well-defined nor computable, so this is
security through obscurity.&lt;/p&gt;
&lt;p&gt;This is just my opinion on the matter. Cryptography texts and/or experienced
cryptographers may disagree.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This definition can be applied to the idea of trying to keep an encryption
algorithm secret. If the security of the algorithm depends on it's secrecy, then
it is security through obscurity, because the amount of work an adversary (who
can run chosen plaintext and chosen ciphertext attacks) has to do to reverse
engineer the algorithm is not well-defined and cannot be computed.&lt;/p&gt;
</summary><category term="obscurity"></category></entry><entry><title>Ruby Obfuscation</title><link href="/blog/ruby-obfuscation.html" rel="alternate"></link><updated>2012-05-28T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-05-28:ruby-obfuscation.html</id><summary type="html">&lt;p&gt;Just having fun...&lt;/p&gt;
&lt;div class="section" id="obfuscated-1"&gt;
&lt;h2&gt;Obfuscated #1&lt;/h2&gt;
&lt;p&gt;This evaluates to the string &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;&amp;quot;?&amp;quot;&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="sc"&gt;??????????????&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;????????&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;??&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;??&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;??&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;??&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="sc"&gt;?????:??&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; &amp;quot;?&amp;quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="obfuscated-2"&gt;
&lt;h2&gt;Obfuscated #2&lt;/h2&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="vg"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="vg"&gt;$c&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[$s=['p '],[$s&amp;lt;&amp;lt;[*1?3??'+?&amp;lt;+?3:?y:?]],$s+=[?b],$s|=[*?y+?'],$s[2,0]=5??r+?u:?$],($i+=1)&amp;lt;30?eval($s.join&amp;lt;&amp;lt;?;&amp;lt;&amp;lt;$c):nil]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nb"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vg"&gt;$c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/pre&gt;
&lt;div class="section" id="output"&gt;
&lt;h3&gt;Output&lt;/h3&gt;
&lt;pre class="code text literal-block"&gt;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&amp;quot;&amp;lt;3ruby&amp;quot;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
</summary><category term="obfuscation"></category></entry><entry><title>Ruby Maze Solver</title><link href="/blog/ruby-maze-solver.html" rel="alternate"></link><updated>2012-05-27T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-05-27:ruby-maze-solver.html</id><summary type="html">&lt;p&gt;Here's a recursive-backtracking ASCII maze solver I wrote to practice ruby. The
&lt;tt class="docutils literal"&gt;o&lt;/tt&gt;'s are the solution.&lt;/p&gt;
&lt;div class="section" id="output"&gt;
&lt;h2&gt;Output&lt;/h2&gt;
&lt;pre class="code text literal-block"&gt;
$ ruby maze.rb maze.txt
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++oooooooo  ++++++++++++++++++++++ ++++++++++++++++++++++++        ++++ ++++++
+oooo++ +++o++++++++++++++++++++++++ ++++ +++++++++++++++++++ +++ +++++++ ++++++
++++ ++   oo+++++++++++++++++++ ++++ ++++                 +++ +++ +++++++ ++++++
++++ ++ ++o++++++++ooooooo+++++ ++++ ++++ +++++++++++++++++++ +++         ++++++
++   +++++o++++++++o+++++o+++++           ++++ ++++++++++++++ ++++++++ +++++++++
++++++++++o++++++++o+++++o+++++ +++++ ++++++++ +++oooooooooooooo++++++ +++++++++
++++++++++o+oooooooo+++++ooooooo+++++ ++++++++ +++o++++++++ +++o++++++ +++++++++
++++++++++ooo++++++++++++ +++++o+++++ +++++++++   o++++++++++++o++++++ +++++++++
+++++++++++++++++++++++++      o++++++++++++++++++o      ++++++o       +++++++++
+++++++ +++++++++++++++++++++++o++++++oooooo++++++o+++++ ++++++o++++++++++++++++
+++++++ +++++++++++++++++++++++o++++++o++++o++++++o+++++ ++++++o++++++++++++++++
++      ++++++++++oooooooooooooo++++++o++++o++++++o+++++ ++++++oooooooo+++++++++
+++++++ ++++++++++o+++++++++++++++++++o++++oooooooo+++++++++++++ +++++o+++++++++
+++++++           o+++++ooooooooooooooo+++++++ +++++++           ++Xooo+++++++++
++++++++++++++++++ooooooo+++++++++++++++++++++ ++++++++++++++++++++F++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="code"&gt;
&lt;h2&gt;Code&lt;/h2&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="c1"&gt;# ------------------------------ Example Maze ------------------------------------&lt;/span&gt;
&lt;span class="c1"&gt;# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# ++++          ++++++++++++++++++++++ ++++++++++++++++++++++++        ++++ ++++++&lt;/span&gt;
&lt;span class="c1"&gt;# +X   ++ +++ ++++++++++++++++++++++++ ++++ +++++++++++++++++++ +++ +++++++ ++++++&lt;/span&gt;
&lt;span class="c1"&gt;# ++++ ++     +++++++++++++++++++ ++++ ++++                 +++ +++ +++++++ ++++++&lt;/span&gt;
&lt;span class="c1"&gt;# ++++ ++ ++ ++++++++       +++++ ++++ ++++ +++++++++++++++++++ +++         ++++++&lt;/span&gt;
&lt;span class="c1"&gt;# ++   +++++ ++++++++ +++++ +++++           ++++ ++++++++++++++ ++++++++ +++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# ++++++++++ ++++++++ +++++ +++++ +++++ ++++++++ +++              ++++++ +++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# ++++++++++ +        +++++       +++++ ++++++++ +++ ++++++++ +++ ++++++ +++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# ++++++++++   ++++++++++++ +++++ +++++ +++++++++    ++++++++++++ ++++++ +++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# +++++++++++++++++++++++++       ++++++++++++++++++       ++++++        +++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# +++++++ +++++++++++++++++++++++ ++++++      ++++++ +++++ ++++++ ++++++++++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# +++++++ +++++++++++++++++++++++ ++++++ ++++ ++++++ +++++ ++++++ ++++++++++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# ++      ++++++++++              ++++++ ++++ ++++++ +++++ ++++++        +++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# +++++++ ++++++++++ +++++++++++++++++++ ++++        +++++++++++++ +++++ +++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# +++++++            +++++               +++++++ +++++++           ++    +++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# ++++++++++++++++++       +++++++++++++++++++++ ++++++++++++++++++++F++++++++++++&lt;/span&gt;
&lt;span class="c1"&gt;# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;
  &lt;span class="n"&gt;printUsage&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;begin&lt;/span&gt;
    &lt;span class="n"&gt;maze&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'r'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;rescue&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Cannot read file.&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;printUsage&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;solver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;MazeSolver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;solver&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;solve&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;solver&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Maze has no solution&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;printUsage&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;USAGE: ruby maze.rb &amp;lt;mazefile&amp;gt;&amp;quot;&lt;/span&gt;
  &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# A recursive backtracking maze solver.&lt;/span&gt;
&lt;span class="c1"&gt;# The maze is specified as an ASCII grid (each line is one row), where:&lt;/span&gt;
&lt;span class="c1"&gt;# - 'X' marks the starting position of the player.&lt;/span&gt;
&lt;span class="c1"&gt;# - 'F' marks the goal.&lt;/span&gt;
&lt;span class="c1"&gt;# - ' ' (space) marks the area where the player is allowed to move.&lt;/span&gt;
&lt;span class="c1"&gt;# - Everything else marks area where the player is NOT allowed to move.&lt;/span&gt;
&lt;span class="c1"&gt;# The maze string must not contain the character 'o' (lowercase oh) since it is&lt;/span&gt;
&lt;span class="c1"&gt;# used to mark the solution path.&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MazeSolver&lt;/span&gt;

  &lt;span class="no"&gt;PLAYER_CHAR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'X'&lt;/span&gt;
  &lt;span class="no"&gt;TRACK_MARKER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'o'&lt;/span&gt;
  &lt;span class="no"&gt;FINISH_CHAR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'F'&lt;/span&gt;
  &lt;span class="no"&gt;SPACE_CHAR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;

  &lt;span class="no"&gt;DELTA_ROW&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="no"&gt;DELTA_COL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

  &lt;span class="c1"&gt;# Movement directions are specified internally by a 'delta', which is an&lt;/span&gt;
  &lt;span class="c1"&gt;# array where [0] is the change in row and [1] is the change in column.&lt;/span&gt;
  &lt;span class="c1"&gt;# The player is only allowed to move up, down, left, and right.&lt;/span&gt;
  &lt;span class="no"&gt;DIRECTIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Split the maze string into an array of arrays of characters.&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;maze&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;maze&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;findPlayer&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Find the player on the maze grid and check that the maze is valid.&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;findPlayer&lt;/span&gt;
    &lt;span class="n"&gt;playerFound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="n"&gt;finishFound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;maze&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_with_index&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rowIndex&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each_with_index&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;colIndex&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;
          &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;PLAYER_CHAR&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'More than one player'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;playerFound&lt;/span&gt;
            &lt;span class="n"&gt;playerFound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
            &lt;span class="vi"&gt;&amp;#64;playerRow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rowIndex&lt;/span&gt;
            &lt;span class="vi"&gt;&amp;#64;playerCol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;colIndex&lt;/span&gt;
          &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;FINISH_CHAR&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;finishFound&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
          &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;TRACK_MARKER&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Track marker playerFound in maze'&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'No player'&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;playerFound&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Solve the maze. Returns true if it has been solved, false if it cannot be solved.&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;solve&lt;/span&gt;
    &lt;span class="n"&gt;possibleMovements&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;moveBy&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;solve&lt;/span&gt;
      &lt;span class="n"&gt;undoMoveBy&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;adjacentToFinish?&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Return an array of valid movement deltas (to SPACE_CHARs) from the current position&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;possibleMovements&lt;/span&gt;
    &lt;span class="n"&gt;deltas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
    &lt;span class="no"&gt;DIRECTIONS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;deltas&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;canMoveBy?&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;deltas&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;moveBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Invalid movement&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;canMoveBy?&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;maze&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerRow&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerCol&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TRACK_MARKER&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;maze&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerRow&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;DELTA_ROW&lt;/span&gt;&lt;span class="o"&gt;]][&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerCol&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;DELTA_COL&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PLAYER_CHAR&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;undoMoveBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;reverse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;maze&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerRow&lt;/span&gt;&lt;span class="o"&gt;][&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerCol&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SPACE_CHAR&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;maze&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerRow&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;DELTA_ROW&lt;/span&gt;&lt;span class="o"&gt;]][&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerCol&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;DELTA_COL&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;PLAYER_CHAR&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;adjacentToFinish?&lt;/span&gt;
    &lt;span class="no"&gt;DIRECTIONS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;&amp;#64;maze&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerRow&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;DELTA_ROW&lt;/span&gt;&lt;span class="o"&gt;]][&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerCol&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;DELTA_COL&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;FINISH_CHAR&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;canMoveBy?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;DELTA_ROW&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;DELTA_COL&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;maze&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerRow&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;DELTA_ROW&lt;/span&gt;&lt;span class="o"&gt;]][&lt;/span&gt;&lt;span class="vi"&gt;&amp;#64;playerCol&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;delta&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="no"&gt;DELTA_COL&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;SPACE_CHAR&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_s&lt;/span&gt;
    &lt;span class="vi"&gt;&amp;#64;maze&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
</summary><category term="search"></category></entry><entry><title>My Favorite 'Rubyisms'</title><link href="/blog/my-favorite-rubyisms.html" rel="alternate"></link><updated>2012-05-16T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-05-16:my-favorite-rubyisms.html</id><summary type="html">&lt;p&gt;I've been using Ruby at work to write &lt;a class="reference external" href="http://watir.com/"&gt;watir&lt;/a&gt; tests, and I am constantly amazed
at how elegant it is. Here are some of my favorite techniques:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pass a default value block to Hash.new to implement a memoized recursive
function:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="n"&gt;fibonacci&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;upto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;fibonacci&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Use an anonymous array to perform some operation on a constant set of things
without repeating yourself:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'golf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'baseball'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'hockey'&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sport&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sport&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;stopPlaying&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sport&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Instead of:&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'golf'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;stopPlaying&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'golf'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'baseball'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;stopPlaying&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'baseball'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hockey'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;stopPlaying&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hockey'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Use an anonymous array to check of some variable is equal to any of a set of things:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Invalid sport'&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'golf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'baseball'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'hockey'&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;include?&lt;/span&gt; &lt;span class="n"&gt;sport&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Instead of:&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s1"&gt;'Invalid sport'&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sport&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;'golf'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;sport&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;'baseball'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;sport&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;'hockey'&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Initialize an array using a range and map, and use rand() with to_s to
generate random strings:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="code ruby literal-block"&gt;
&lt;span class="n"&gt;randomStrings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;testUser%d&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;
</summary><category term="ruby"></category></entry><entry><title>The Economics of Password Cracking</title><link href="/blog/the-economics-of-password-cracking.html" rel="alternate"></link><updated>2012-05-05T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-05-05:the-economics-of-password-cracking.html</id><summary type="html">&lt;p&gt;We know that it's possible to come up with a password that no computer on earth
can crack. Use true random data to generate a sequence of 20 characters from the
full ASCII printable set, spend an hour memorizing, and you're good. We also
know that most people don't do that. What we don't know (or at least often
forget) is that people don't need to do that.&lt;/p&gt;
&lt;p&gt;We estimate our password strength by the amount of time it would take the
fastest imaginable supercomputer to search through the set of all passwords of
equal or less length and find ours. What we often forget is that the bad guys
don't have those kinds of resources, and they rarely ever crack passwords via
brute-force search.&lt;/p&gt;
&lt;p&gt;Why not? Because most bad guys won't build a billion-dollar supercomputer to
crack one password, and most people with billion-dollar supercomputers aren't
willing to rent out their processing power for password cracking. It isn't
profitable, and those supercomputers can be used for better things like
scientific research.&lt;/p&gt;
&lt;p&gt;The Bitcoin network is currently computing 11.74 trillion sha256 hashes per
second (&lt;a class="reference external" href="http://bitcoinwatch.com/"&gt;see here for current stats&lt;/a&gt;). The network will compute &lt;tt class="docutils literal"&gt;3.702x10^20&lt;/tt&gt;
hashes in one year if it continues at it the same rate (my guess is that it will
grow, but it's already over 10 times as powerful as &lt;cite&gt;the fastest known
supercomputer&lt;/cite&gt;).  That may seem like a lot of hashes, but if you do the math,
you'll see that its not even enough to do a brute-force search through the set
of all 11-character ASCII passwords. &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;log(3.702x1020)/log(95)&lt;/span&gt; = 10.40&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Read it again: &lt;strong&gt;The Bitcoin network is made up of millions of dollars worth of
hardware and is 10x faster than the fastest known supercomputer, but it can not
brute-force guess an 11-character password in a year.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There is no business model that makes brute-force password cracking profitable.
To see why, consider the following argument:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;If the password can't be cracked with good quality dictionaries or rainbow
tables, it is long and complex.&lt;/li&gt;
&lt;li&gt;Since the fastest distributed computing network on earth can barely search
through the set of all 10-character ASCII passwords in a year, the
probability of cracking a long and complex password via brute-force search in
a reasonable amount of time is low.&lt;/li&gt;
&lt;li&gt;Since the probability of successfully cracking a password via brute-force is
low, to make any money, you must charge the customer even if you cannot crack
it.&lt;/li&gt;
&lt;li&gt;Since the probability of successfully cracking a password via brute-force is
low, and the customer must pay even if you cannot crack it, the customer will
not be willing to pay very much.&lt;/li&gt;
&lt;li&gt;A decent brute-force attack requires a lot of time on an expensive
supercomputer, so you must charge a lot.&lt;/li&gt;
&lt;li&gt;(4) and (5) are incompatible with each other, so it is impossible to run
a profitable brute-force cracking business.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Of course (4) may not hold true when the customer is a government and the
password is the key to winning a war, but most passwords don't have that much
value.&lt;/p&gt;
&lt;p&gt;What this tells us is that we don't need to worry about brute-force attacks.
They always succeed (by definition), but rarely in a reasonable amount of time
and there is rarely ever a password valuable enough to justify one.&lt;/p&gt;
&lt;p&gt;So ironically, the most profitable kind of password cracking requires very
little computational resources (a single 6-core system satisfies
&lt;a class="reference external" href="https://crackstation.net/"&gt;crackstation.net&lt;/a&gt;'s needs). The key to being profitable in the password
cracking industry is to be clever and do as much as you can without
a supercomputer. That means implementing extremely fast look-up tables and
constructing extremely effective dictionaries -- going after the low-hanging
fruit.&lt;/p&gt;
&lt;p&gt;That's exactly what the bad guys do, and that's exactly what my hash cracking
service does. If you want your password to be secure, don't worry about
comparing its strength to a hypothetical supercomputer, just make sure it's not
a low-hanging fruit, and make brute-force search the only option for your
adversary. Then they probably won't even bother trying.&lt;/p&gt;
&lt;p&gt;The easiest way to get out of the low-hanging fruit zone is to make your
password long. Take a look at &lt;a class="reference external" href="https://www.grc.com/haystack.htm"&gt;GRC's Password Haystacks&lt;/a&gt; page for some good
advice.&lt;/p&gt;
&lt;p&gt;Here's a tip: My hash cracking service is backed by the largest known password
cracking dictionary, which has just over 15 billion entries. There are over
7 billion possible 5-character ASCII strings. So if you include 5 random ASCII
characters in your password and pad it out to at least 12 characters with
something memorable (not a word!), you can be pretty sure that your password
isn't a low-hanging fruit.&lt;/p&gt;
</summary><category term="passwords"></category><category term="hashing"></category><category term="cracking"></category></entry><entry><title>Random .vimrc Tips</title><link href="/blog/random-vimrc-tips.html" rel="alternate"></link><updated>2012-04-29T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-04-29:random-vimrc-tips.html</id><summary type="html">&lt;p&gt;Here are some of my favorite .vimrc lines.&lt;/p&gt;
&lt;p&gt;Save quickly from any mode by pressing CTRL+:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
imap &amp;lt;C-\&amp;gt; &amp;lt;Esc&amp;gt;:w&amp;lt;Cr&amp;gt;
map &amp;lt;C-\&amp;gt; &amp;lt;Esc&amp;gt;:w&amp;lt;Cr&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Make indenting and de-indenting in visual mode preserve the selection:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
vnoremap &amp;gt; &amp;gt;&amp;lt;CR&amp;gt;gv
vnoremap &amp;lt; &amp;lt;&amp;lt;CR&amp;gt;gv
&lt;/pre&gt;
&lt;p&gt;Quick case insensitive search with double slash or double question mark:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
map // /\c
map ?? ?\c
&lt;/pre&gt;
&lt;p&gt;Make the j and k keys move up by a line on the screen rather than a line in the
file (very useful when navigating a long line that has wrapped many times):&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
map j gj
map k gk
&lt;/pre&gt;
&lt;p&gt;Highlight column 80 (Vim 7.3+ only):&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
if v:version &amp;gt;= 703
    set cc=80
    hi ColorColumn ctermbg=Gray ctermfg=Black guibg=#404040
    command Skinny set cc=73
    command Wide set cc=80
endif
&lt;/pre&gt;
&lt;p&gt;Don’t show the splash screen:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
set shortmess+=I
&lt;/pre&gt;
&lt;p&gt;Keep the cursor 4 lines away from the top or bottom to automatically preserve
context when editing near the top or bottom of the window:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
set scrolloff=4
&lt;/pre&gt;
&lt;p&gt;Make CTRL+u and CTRL+d less confusing:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
map &amp;lt;C-u&amp;gt; 10&amp;lt;C-Y&amp;gt;10k
map &amp;lt;C-d&amp;gt; 10&amp;lt;C-E&amp;gt;10j
&lt;/pre&gt;
&lt;p&gt;Scroll the screen with ALT+{j,k}:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
map &amp;lt;A-j&amp;gt; 2&amp;lt;C-E&amp;gt;
map &amp;lt;A-k&amp;gt; 2&amp;lt;C-Y&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Easy paste toggle:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
&amp;quot; Allow middle-click pasting of large texts in terminal
set pastetoggle=&amp;lt;F5&amp;gt;
&amp;quot; Clear paste mode when going back to normal mode
au InsertLeave * set nopaste
&lt;/pre&gt;
&lt;p&gt;Switch windows quickly with CTRL+{h,j,k,l}:&lt;/p&gt;
&lt;pre class="code text literal-block"&gt;
&amp;quot; This breaks backspace in a terminal, but I never use backspace in normal mode
map &amp;lt;C-h&amp;gt; &amp;lt;C-W&amp;gt;h
map &amp;lt;C-j&amp;gt; &amp;lt;C-W&amp;gt;j
map &amp;lt;C-k&amp;gt; &amp;lt;C-W&amp;gt;k
map &amp;lt;C-l&amp;gt; &amp;lt;C-W&amp;gt;l
&amp;quot; This would break in a terminal where ^H is backspace.
if has(&amp;quot;gui_running&amp;quot;)
    imap &amp;lt;C-h&amp;gt; &amp;lt;Esc&amp;gt;&amp;lt;C-W&amp;gt;h
endif
imap &amp;lt;C-j&amp;gt; &amp;lt;Esc&amp;gt;&amp;lt;C-W&amp;gt;j
imap &amp;lt;C-k&amp;gt; &amp;lt;Esc&amp;gt;&amp;lt;C-W&amp;gt;k
imap &amp;lt;C-l&amp;gt; &amp;lt;Esc&amp;gt;&amp;lt;C-W&amp;gt;l
&lt;/pre&gt;
&lt;p&gt;&lt;a class="reference external" href="https://defuse.ca/vimrc.htm"&gt;Click here for my entire Vim configuration.&lt;/a&gt;&lt;/p&gt;
</summary><category term="vim"></category></entry><entry><title>Clipboard over SSH with Vim</title><link href="/blog/clipboard-over-ssh-with-vim.html" rel="alternate"></link><updated>2012-04-28T00:00:00-06:00</updated><author><name>Taylor Hornby</name></author><id>tag:/blog,2012-04-28:clipboard-over-ssh-with-vim.html</id><summary type="html">&lt;p&gt;The following is a simple and easy way to get clipboard sharing with Vim working
between two Linux installations (specifically a desktop and remote server).&lt;/p&gt;
&lt;p&gt;First install &lt;tt class="docutils literal"&gt;xclip&lt;/tt&gt; on both your local machine and the server:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
apt-get install xclip
&lt;/pre&gt;
&lt;p&gt;Installing &lt;tt class="docutils literal"&gt;xclip&lt;/tt&gt; will bring along some dependencies like &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;x11-common&lt;/span&gt;&lt;/tt&gt;, but
don't worry, you don't need to run an X server on the server to get this
working.&lt;/p&gt;
&lt;p&gt;Next, enable X11 forwarding on the server. Add the following to
&lt;tt class="docutils literal"&gt;/etc/ssh/sshd_config&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
X11Forwarding yes
&lt;/pre&gt;
&lt;p&gt;Then add the following to the server's &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.vimrc&lt;/span&gt;&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="code bash literal-block"&gt;
vmap &lt;span class="s2"&gt;&amp;quot;+y :!xclip -f -sel clip
map &amp;quot;&lt;/span&gt;+p :r!xclip -o -sel clip
&lt;/pre&gt;
&lt;p&gt;This will remap the &lt;tt class="docutils literal"&gt;&amp;quot;+y&lt;/tt&gt; (copy) and &lt;tt class="docutils literal"&gt;&amp;quot;+p&lt;/tt&gt; (paste) commands to use
&lt;tt class="docutils literal"&gt;xclip&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Now you're done. SSH into the server with &lt;tt class="docutils literal"&gt;ssh &lt;span class="pre"&gt;-X&lt;/span&gt;&lt;/tt&gt;, fire up vim, and see if it
works. If you don't want to type &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-X&lt;/span&gt;&lt;/tt&gt; every time, you can add &lt;tt class="docutils literal"&gt;ForwardX11
yes&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;/etc/ssh/ssh_config&lt;/tt&gt; on your local machine to make it always try to
forward X.&lt;/p&gt;
&lt;p&gt;Source: &lt;a class="reference external" href="http://vim.wikia.com/wiki/GNU/Linux_clipboard_copy/paste_with_xclip"&gt;http://vim.wikia.com/wiki/GNU/Linux_clipboard_copy/paste_with_xclip&lt;/a&gt;&lt;/p&gt;
</summary><category term="clipboard"></category><category term="ssh"></category></entry></feed>