<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Absolutely No Machete Juggling</title>
	<atom:link href="http://www.nomachetejuggling.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nomachetejuggling.com</link>
	<description>How a random programmer views the world.</description>
	<pubDate>Mon, 28 Apr 2008 20:36:24 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>en</language>
			<item>
		<title>Assert_tag With Two Siblings In Rails</title>
		<link>http://www.nomachetejuggling.com/2008/04/28/assert_tag-with-two-siblings-in-rails/</link>
		<comments>http://www.nomachetejuggling.com/2008/04/28/assert_tag-with-two-siblings-in-rails/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 20:33:35 +0000</pubDate>
		<dc:creator>Rod</dc:creator>
		
		<category><![CDATA[Computers]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[tests]]></category>

		<guid isPermaLink="false">http://www.nomachetejuggling.com/?p=126</guid>
		<description><![CDATA[I was recently dealing with a tricky problem while writing some rails tests.
I was writing assert_tags against xml returned by a rails web service in order to test that the xml contained specific values. 
Here is a sample of the XML:
&#60;elements&#62;
  &#60;element&#62;
    &#60;name&#62;rod&#60;/name&#62;
    &#60;surname&#62;hilton&#60;/surname&#62;
    &#60;value&#62;123&#60;/value&#62;
 [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently dealing with a tricky problem while writing some rails tests.</p>
<p>I was writing assert_tags against xml returned by a rails web service in order to test that the xml contained specific values. </p>
<p>Here is a sample of the XML:</p>
<pre class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;elements<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;element<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;name<span style="font-weight: bold; color: black;">&gt;</span></span></span>rod<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/name<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;surname<span style="font-weight: bold; color: black;">&gt;</span></span></span>hilton<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/surname<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;value<span style="font-weight: bold; color: black;">&gt;</span></span></span>123<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/value<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/element<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;element<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;name<span style="font-weight: bold; color: black;">&gt;</span></span></span>rod<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/name<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;surname<span style="font-weight: bold; color: black;">&gt;</span></span></span>smith<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/surname<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;value<span style="font-weight: bold; color: black;">&gt;</span></span></span>456<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/value<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/element<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;element<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;name<span style="font-weight: bold; color: black;">&gt;</span></span></span>granny<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/name<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;surname<span style="font-weight: bold; color: black;">&gt;</span></span></span>smith<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/surname<span style="font-weight: bold; color: black;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;value<span style="font-weight: bold; color: black;">&gt;</span></span></span>789<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/value<span style="font-weight: bold; color: black;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/element<span style="font-weight: bold; color: black;">&gt;</span></span></span>
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/elements<span style="font-weight: bold; color: black;">&gt;</span></span></span></pre>
<p>I want to write three assertions.  If I write this in my test, it will work as expected:</p>
<pre class="ruby">assert_tag :tag=&gt;<span style="color:#996600;">&quot;value&quot;</span>, :content=&gt;<span style="color:#996600;">&quot;789&quot;</span>,
           :sibling=&gt;<span style="color:#006600; font-weight:bold;">&#123;</span>:tag=&gt;<span style="color:#996600;">&quot;name&quot;</span>, :content=&gt;<span style="color:#996600;">&quot;granny&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span></pre>
<p>Basically what I'm doing is looking for a value element with the content of 789, and it has to have a sibling of a name element with the content "granny", which assures it will select the last "element" for the value.</p>
<p>The problem is, how do I write a test for the first xml element?  If I look for a sibling with name "rod", it's possible that I'd select the second element.  If look for a sibling with the surname "smith", it's possible that I'd select granny again.  I need to be able to select the tag with TWO siblings.</p>
<p>The documentation is not straightforward about how to do this, but I figured out a method that works.</p>
<p>Essentially, the :sibling hash element takes the same kind of hash that assert_tag takes.  Meaning, you can pass anything into :sibling that you would pass to assert_tag to begin with - including another sibling!</p>
<pre class="ruby">assert_tag :tag=&gt;<span style="color:#996600;">&quot;value&quot;</span>, :content=&gt;<span style="color:#996600;">&quot;123&quot;</span>,
           :sibling=&gt;<span style="color:#006600; font-weight:bold;">&#123;</span>
             :tag=&gt;<span style="color:#996600;">&quot;name&quot;</span>, :content=&gt;<span style="color:#996600;">&quot;rod&quot;</span>,
             :sibling=&gt;<span style="color:#006600; font-weight:bold;">&#123;</span>
               :tag=&gt;<span style="color:#996600;">&quot;surname&quot;</span>, :content=&gt;<span style="color:#996600;">&quot;hilton&quot;</span>
             <span style="color:#006600; font-weight:bold;">&#125;</span>
           <span style="color:#006600; font-weight:bold;">&#125;</span></pre>
<p>Pretty insane, but I wasn't able to figure out a better way.  I was hoping to pass an array of hashes to :sibling, but that didn't work as I had hoped.</p>
<p>If anyone has a better way than this, feel free to leave a comment.  Otherwise, this seems to be a relatively readable way of selecting tags with 2 (or more) siblings in assertions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomachetejuggling.com/2008/04/28/assert_tag-with-two-siblings-in-rails/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Setting JAVA_HOME in a Batch File</title>
		<link>http://www.nomachetejuggling.com/2008/04/04/setting-java_home-in-batch-file/</link>
		<comments>http://www.nomachetejuggling.com/2008/04/04/setting-java_home-in-batch-file/#comments</comments>
		<pubDate>Fri, 04 Apr 2008 15:38:42 +0000</pubDate>
		<dc:creator>Rod</dc:creator>
		
		<category><![CDATA[Computers]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[batch]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.nomachetejuggling.com/?p=125</guid>
		<description><![CDATA[Recently at work I had a bizarre problem to deal with.  Essentially, we are distributing an application that uses JRuby, and we were encountering a problem whenever people would use our application in Windows if they installed Java in a specific way.
A lot of Windows users install Java not by putting the bits on [...]]]></description>
			<content:encoded><![CDATA[<p>Recently at work I had a bizarre problem to deal with.  Essentially, we are distributing an application that uses <a href="http://jruby.codehaus.org/">JRuby</a>, and we were encountering a problem whenever people would use our application in Windows if they installed Java in a specific way.</p>
<p>A lot of Windows users install Java not by putting the bits on disk and setting JAVA_HOME, but by adding java.exe to their path.  When done this way, Java works in the sense that you can type "java" in a command prompt and have it understand what that means.  You can compile java from command line and run it with no problem.</p>
<p>The problem we experienced was that JRuby, in windows, specifically looks to see if JAVA_HOME is set.  If it is not set, the JRuby executable bails.  I submitted a <a href="http://jira.codehaus.org/browse/JRUBY-2301">patch</a> to JRuby to fix this behavior, but we could not rely on that solution until it was integrated.</p>
<p>What we are doing now is, in the batch file that we have that calls our application, we look to see if JAVA_HOME is set and, if it is not, step through the PATH looking for java.exe.  We then set JAVA_HOME based on the location.  As a result, by the time the JRuby script runs, JAVA_HOME has been set.</p>
<p>This is actually a handy trick to look for anything in the path in a Windows batch file.</p>
<p>Here's the code:</p>
<pre class="winbatch"><span style="color: #800080;">if</span> not <span style="color: #ff0000;">&quot;%JAVA_HOME%&quot;</span> == <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #800080;">goto</span> javaHomeAlreadySet
<span style="color: #800080;">for</span> %%P <span style="color: #800080;">in</span> <span style="color: #66cc66;">&#40;</span>%PATH%<span style="color: #66cc66;">&#41;</span> do <span style="color: #800080;">if</span> exist %%P\java.exe set JAVA_HOME=%%P..\
<span style="color: #FF1010; font-weight: bold;">:javaHomeAlreadySet</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.nomachetejuggling.com/2008/04/04/setting-java_home-in-batch-file/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Holy Shit, I&#8217;ve Been Hacked</title>
		<link>http://www.nomachetejuggling.com/2008/04/01/holy-shit-ive-been-hacked/</link>
		<comments>http://www.nomachetejuggling.com/2008/04/01/holy-shit-ive-been-hacked/#comments</comments>
		<pubDate>Wed, 02 Apr 2008 01:34:30 +0000</pubDate>
		<dc:creator>Rod</dc:creator>
		
		<category><![CDATA[Computers]]></category>

		<category><![CDATA[Life]]></category>

		<category><![CDATA[Security]]></category>

		<category><![CDATA[funny]]></category>

		<category><![CDATA[hacking]]></category>

		<category><![CDATA[site]]></category>

		<category><![CDATA[story]]></category>

		<guid isPermaLink="false">http://www.nomachetejuggling.com/2008/04/01/holy-shit-ive-been-hacked/</guid>
		<description><![CDATA[Apparently there is some wordpress vulnerability that allows someone to replace my header file with a whole bunch of viagra links.  Awesome.
Anyway, it actually overwrote the file on the server, so my design is all busted and I don't have it backed up in any way. 
I'll be upgrading wordpress and fixing my site [...]]]></description>
			<content:encoded><![CDATA[<p>Apparently there is some wordpress vulnerability that allows someone to replace my header file with a whole bunch of viagra links.  Awesome.</p>
<p>Anyway, it actually overwrote the file on the server, so my design is all busted and I don't have it backed up in any way. </p>
<p>I'll be upgrading wordpress and fixing my site theme.  This may take some time.  Bear with me.</p>
<p>No, this is not an April fools thing.  I actually got haxx0red, for realz. :/</p>
<p><b>Update:</b> Alright, I've upgraded wordpress and removed the viagra links.  It appears that someone was able to override my footer and header.php files for my theme.  To an extent, I'm not terribly surprised, as those files are set world writable so that wordpress can write to them, allowing me to edit from the admin console.  </p>
<p>This whole thing could have been much worse.  The hack left my database untouched, all of my blog posts look the way they are supposed to.  All it did was modify the files to my theme.</p>
<p>That said, because it so thoroughly destroyed my theme and I didn't back my theme up on my local machine (it's just a blog), I have set the site to use the default ugly wordpress theme until I can work up another one.  It's just as well, I was sick of the old one anyway.</p>
<p><b>Extra Update</b>: I just wanted to share the comment that informed me something was wrong with my site.  It's humorous.  These were both anonymous:</p>
<blockquote><p>
Real quick…I want an explanation for what the hell happened to your site or I’m reporting it to your hosting company and to Google. Two days ago I found this post and this site through Silicon Alley Insider and bookmarked it because I liked the blog design and wanted to work on something around it. I come back tonight and obviously the CSS file is gone. I clicked “view source” and not only is there no CSS file, there is no document head, no robots file, but there are about a thousand links to spam drug sites embedded in the source? You really don’t want me screencapping and posting this here and there, and you definitely don’t even want me to get started with Google, of all companies, reporting your ass if this isn’t a case of a your website being hacked.</p></blockquote>
<p>Then later, same person:</p>
<blockquote><p>You can hold my comments for moderation, I don’t care. I think you’re fucked either way. Looks like this site is owned and operated by the (fictitious?) Rod Hilton, whose own website is on a Google server. Try explaining that and all the spam links served to this site dynamically, viewable in the page source, before I get going on explaining it for you. You definitely don’t need to show my comments here to bury yourself in a world of shit.</p></blockquote>
<p>Jesus, what a spazz.  Well, thanks for letting me know my site was hacked, even if you did so by being a crazy person.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomachetejuggling.com/2008/04/01/holy-shit-ive-been-hacked/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How To Play Peter Rottentail</title>
		<link>http://www.nomachetejuggling.com/2008/03/16/how-to-play-peter-rottentail/</link>
		<comments>http://www.nomachetejuggling.com/2008/03/16/how-to-play-peter-rottentail/#comments</comments>
		<pubDate>Sun, 16 Mar 2008 22:41:08 +0000</pubDate>
		<dc:creator>Rod</dc:creator>
		
		<category><![CDATA[Life]]></category>

		<category><![CDATA[easter]]></category>

		<category><![CDATA[holiday]]></category>

		<guid isPermaLink="false">http://www.nomachetejuggling.com/2008/03/16/how-to-play-peter-rottentail/</guid>
		<description><![CDATA[I hate Easter.  In fact, with the exception of Halloween, I hate pretty much all holidays.  I hate easter in particular though.  Growing up, Christmas was the present holiday and Easter was the candy holiday, and I couldn't care less about most candy (at least when compared to presents).  Easter was [...]]]></description>
			<content:encoded><![CDATA[<p>I hate Easter.  In fact, with the exception of Halloween, I hate pretty much all holidays.  I hate easter in particular though.  Growing up, Christmas was the present holiday and Easter was the candy holiday, and I couldn't care less about most candy (at least when compared to presents).  Easter was a no big deal kind of day for me.  It meant I had to wear khakis to church, but that's about it.</p>
<p>However, my fiancee comes from a Catholic family, and Easter was a very big deal to them.  They hid eggs, they hid baskets, they got presents, the whole deal.  So as she and I integrate our lives together, doing something for easter is important, but I don't particularly like any of the egg-hiding mumbo jumbo.  At least I didn't, until this year.</p>
<p><i>I have devised a system that makes Easter fun.   It is a game that I have dubbed 'Peter Rottentail'.</i></p>
<p>Peter Rottentail essentially turns innocent and lame Easter festivities into seedy gambling events.  I will detail the rules of how to play Peter Rottentail in this post.  This is a great game to play for people without any kids who want to do something for Easter.</p>
<p><span id="more-121"></span></p>
<p><strong>How To Play Peter Rottentail</strong></p>
<p>Each player starts the game with an easter basket.  Then each player must purchase easter eggs, at $1 per egg, with a maximum of five eggs.  You can choose to play $5 or $10 per egg if you wish.  Each player then writes her initials on her eggs with a wax crayon and dyes them, placing them in her basket.  All of the money goes in another basket, referred to as the "Easter Cashket"</p>
<p>Once all of the eggs are created, all players have 10 minutes to walk around the Easter Zone (defined later) and get hiding place ideas.  All players then leave the house with their baskets of eggs.</p>
<p>One by one, players are chosen at random (this can be done by rolling dice, flipping coins, etc).  The chosen player takes one egg from their basket, enters the house, and hides it within the Easter Zone.  They have one minute to do so.  If they do not come back out within one minute, they forfeit one egg of theirs, which will not be hidden (called a Penalty Egg)  </p>
<p>If a player finds another players egg while hiding their own, they may exit the house with it and place it in the appropriate player's basket (another type of Penalty Egg).</p>
<p>This repeats until all eggs have been hidden excluding penalty eggs, which stay in the baskets of the penalized players, giving them a disadvantage in the game.</p>
<p>Once all eggs are hidden, everyone reenters the house with their baskets, placing them in a community area.</p>
<p>Then everyone searches for eggs.  When you find an egg, you place that egg in the basket of the player who created that egg.  Once all of a player's eggs have been placed in his or her basket, that player has been eliminated.  The player that located the Killing Egg yells that the player has been eliminated, and the eliminated player must sit in the community area like a chump waiting for the game to end.  </p>
<p>Once all players but one have been eliminated, a winner is declared.  The winner must then go and locate all of the eggs they hid that were not found.  Failure to locate all hidden eggs will result in an automatic disqualification, and the winner will be the last player eliminated.</p>
<p>The winner collects the Easter Cashket, and may proceed to gloat and mock the other players for hiding their eggs so poorly.</p>
<p><strong>The Easter Zone</strong></p>
<p>The easter zone is the area of the home where eggs are allowed to be hidden.  Each host of Peter Rottentail may define this zone.  Hiding an egg outside of the zone will result in disqualification and automatic forfeiture of contribution to Easter Cashket.</p>
<p>It is a good idea to exclude certain rooms you don't want destroyed from the Easter Zone.  For example, we exclude our bedroom closet, as people rummaging around in there would make a tremendous mess.  We also include places we don't want to have to search - for example, all trash cans, litter boxes, and toilet tanks are excluded from the Easter Zone.</p>
<p>Explaining to your guests where the easter zone is provides a good opportunity to let people take the 10 minutes they need to think of hiding ideas.  You don't want people to think very long about hiding spots once inside - that's why a 1 minute limit is placed on hiding eggs (it prevents people from doing things like dismantling your air conditioning vents to hide eggs).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomachetejuggling.com/2008/03/16/how-to-play-peter-rottentail/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Using Multiple Versions Of Rails</title>
		<link>http://www.nomachetejuggling.com/2008/03/12/using-multiple-versions-of-rails/</link>
		<comments>http://www.nomachetejuggling.com/2008/03/12/using-multiple-versions-of-rails/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 05:32:09 +0000</pubDate>
		<dc:creator>Rod</dc:creator>
		
		<category><![CDATA[Computers]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.nomachetejuggling.com/2008/03/12/using-multiple-versions-of-rails/</guid>
		<description><![CDATA[It's quite easy to have multiple versions of rails installed as gems when working with ruby on rails.  Quite frequently, you will be working on a project that uses an older version of rails than one on your machine, and all you have to do to get the correct version is:

gem install -v 1.2.3 [...]]]></description>
			<content:encoded><![CDATA[<p>It's quite easy to have multiple versions of rails installed as gems when working with ruby on rails.  Quite frequently, you will be working on a project that uses an older version of rails than one on your machine, and all you have to do to get the correct version is:</p>
<pre>
gem install -v 1.2.3 rails --include-dependencies
</pre>
<p>Multiple versions of rails can exist independently on your machine without much of a problem.  Since your individual rails projects store the version number they expect, and your projects don't tend to depend on each other, you can have hundreds of different rails versions installed and never notice. Mostly.</p>
<p>If, however, you wish to start a NEW project, when you run</p>
<pre>
rails projectname
</pre>
<p>It will use the most recent version of rails.  But what if, for some reason, you have rails 2.0.1 and rails 1.2.6 on your machine, and wish to generate a rails 1.2.6 application?  This came up because I'm trying to teach a friend rails, and the book he has is for rails 1.2, meaning that if he uses 2.0 all of the scaffolding code (as well as other bits) from the book are incorrect.  At the same time, the application he and I are working on together uses rails 2.0, so he needs both versions on his machine.</p>
<p>This solution works in linux (haven't tried windows):</p>
<pre>
rails _1.2.6_ projectname
</pre>
<p>I didn't see any documentation about this anywhere.  In fact, I found it by cracking open the actual 'rails' script in /usr/bin and noticing that it did a regex match for a parameter that started and ended with underscores, then interpreted that as the version.</p>
<p>In any case, this allows you to happily generate a new rails app using an old version of rails.  Nothing quite like discovering an undocumented feature by reading the source code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomachetejuggling.com/2008/03/12/using-multiple-versions-of-rails/feed/</wfw:commentRss>
		</item>
		<item>
		<title>My First Caucus: The Tale Of The Reluctant Delegate</title>
		<link>http://www.nomachetejuggling.com/2008/02/08/my-first-caucus-the-tale-of-the-reluctant-delegate/</link>
		<comments>http://www.nomachetejuggling.com/2008/02/08/my-first-caucus-the-tale-of-the-reluctant-delegate/#comments</comments>
		<pubDate>Fri, 08 Feb 2008 23:49:57 +0000</pubDate>
		<dc:creator>Rod</dc:creator>
		
		<category><![CDATA[Culture]]></category>

		<category><![CDATA[Life]]></category>

		<category><![CDATA[Politics]]></category>

		<category><![CDATA[story]]></category>

		<guid isPermaLink="false">http://www.nomachetejuggling.com/2008/02/08/my-first-caucus-the-tale-of-the-reluctant-delegate/</guid>
		<description><![CDATA[This past Super Tuesday, I participated in the Caucus in Colorado.  This was my first experience doing anything like this.  I vote in every election, but typically I have absentee ballots mailed to me in order to vote.  I'm normally registered as an independent, so I can't do much more than vote [...]]]></description>
			<content:encoded><![CDATA[<p>This past Super Tuesday, I participated in the Caucus in Colorado.  This was my first experience doing anything like this.  I vote in every election, but typically I have absentee ballots mailed to me in order to vote.  I'm normally registered as an independent, so I can't do much more than vote in the election itself anyway. This year, however, was quite different.   I actually got involved.</p>
<p>Getting involved, in short, sucked.  This is my story of why.  Normally I would put pictures into a post this long, but I didn't realize until the Caucus was over that it was going to be such a ridiculous experience as to warrant a blog post, so I didn't take any pictures.  Good for you if you manage to get through all of this anyway.</p>
<p><strong>Background</strong></p>
<p>For the first time, hearing a politician speak actually got me excited.  Normally I view voting as a choice between the lesser of two evils, but for the first time a candidate was talking about things that really mattered to me.  Ron Paul talked not only about how we shouldn't be in Iraq, but about how our foreign policy is actually making us less safe, from a practical standpoint.  Ron Paul talked about how the executive branch has gotten too powerful, and it needed to be trimmed back.  He talked about empowering states, and he talked about decreasing the overall power of the federal government.  These were all things that were important to me, and hearing a person actually running for president talking about those things got me excited enough that I registered as a republican so I could support him.</p>
<p>Now, that was many months ago.  Since that time, my support for Ron Paul has decreased.  Not dramatically, but I'm nowhere near as enthusiastic as I was once.  While the idea of adopting the gold standard for currency and abolishing the IRS both appeal to me, they both seem too extreme to do anything other than hurt the country.  Ron Paul's stances on technology greatly irritate me - particularly that people trumpet it as a good thing (many clamor that "he voted against regulating the internet" like it's a reason to vote for him.  I don't think people understand that was a vote AGAINST <a href="http://en.wikipedia.org/wiki/Net_neutrality">Net Neutrality</a>).  He has pushed numerous pieces of legislation forward that seem to contradict his world view of limited federal government, most notably bills that have to do with his personal religious beliefs.  He is pro-life (I'm not).  He trusts the free market a bit too much for my personal taste (a common problem with Libertarian candidates, who would seemingly like to remove things like the FDA).  Despite all of these reasons (which would normally make a candidate lose my support), he still trumpets more than any other candidate how important our civil liberties are.  In a "post 9/11 world", it's rare to see a politician actually espouse the position that our liberties are more important than our safety, and Ron Paul still does - vehemently.  The short of all of this is that, by the time the caucus rolled around I was still a big Ron Paul Fan, but I was no longer a Ron Paul Zealot.  </p>
<p>At the same time, Barack Obama was talking about a lot of things that mattered to me as well: the war, civil liberties, the war on drugs, and he also got bonus points for his views on technology.  Between Obama and Ron Paul, I would have a hard decision to make.  Yes, the two disagree on a LOT, but that doesn't mean it's impossible for me to support either one.  Support for Paul would only exclude support for Obama if I supported ALL of Ron Paul's policies, which I do not.  Their overlap is significant, and they both appeal to different aspects of what is important to me.</p>
<p>By February 5th, the republicans still in the running were Mike Huckabee, Ron Paul, Mitt Romney and John McCain.  Of those four, Ron Paul is, in my opinion, the best candidate by miles.  There was no need, at that point, to consider the fact that I was growing increasingly partial to Obama, since Obama wasn't running as a republican.  On February 5th, I had two options: one, I could stay home and not participate at all on the grounds that I might not vote for Ron Paul if he were running against Obama, or two, I could recognize that Paul is the best republican of the bunch, and as a registered Republican I only had a say in the Republican Caucus.</p>
<p>I figured that the experience alone was worth the price of attending.  I had specifically registered as a Republican in order to support Paul, so I figured I may as well do just that.  It was either that or do nothing, so I picked do something.</p>
<p>Next time I do something "for the experience", I may want to think twice.</p>
<p><span id="more-118"></span></p>
<p><strong>Preparing For The Caucus</strong></p>
<p>I told my fiancee that I'd be home in a few hours.  I expected to go to the Caucus, find the Ron Paul delegates, vote for them, and go home.  I wound up getting home 7 hours later, but I'm getting ahead of myself.</p>
<p>Apparently only about fifty people showed up to the Caucus 2 years ago (not surprising since it was a midterm election) and only about 20 showed up in 2004 (not surprising since Bush was the incumbent).  In 2000, Colorado used a traditional Primary system.  Basically, the people running the show simply had no idea that over 800 people were going to show up for this thing, and they were not prepared for it.</p>
<p>Parking was a challenge.  I had to drive into a nearby subdivision and park next to some random person's house, then walk about half a mile to the school.  As I walked past lines of cars with "Respect Life" license plates and "Bush '04" bumper stickers, I began to wonder if perhaps I was making the wrong choice.  I felt like I was infiltrating a secret society.</p>
<p>Once I got to the middle school where my county's caucus was held, I walked inside only to discover that the line to check in started outside, then to the front door of the school, then to the back of the school, then curved and came all the way back up to the front door.  Then it curved again, went all the way back, and then back to the front again where the table was.  Needless to say, check-in took hours.  I was able to stand in line for quite some time, making observations about those around me.  Here are the main generalizations I walked away with:</p>
<ul>
<li><b>Republicans are all white</b>.  I realize that this is a common stereotype, but I had never seen it so well illustrated.  There wasn't a single non-white person in the whole crowd of 800 that I could see.  No black people, no latino people, no asian people.  Just white folks.  I realize I'm in Colorado, but damn.</li>
<li><b>Republicans love to bash democrats</b>.  Most people, when they have nothing to talk about, discuss the weather.  In a uniformly republican setting, republicans like to bag on democrats.  At one point, a lady with a baby asked if she could cut through the line outside to get indoors so her baby wouldn't be cold.  I made some crack about the baby being a registered voter, and the people nearly responded with 100 variations of "no, you're thinking of democrats." Ugh.</li>
<li><b>Republican women are either old or hot.</b>.  There was no middle ground.  Most of the women were silver-haired old ladies that looked on the verge of death.  All of the other women, however, looked like they walked out of a magazine.  Whenever I see democrats assembled together, the women all look like unshowered, fat hippies.  I don't get it.</li>
</ul>
<p>Eventually I got to the check-in table.  The lady took my driver's license and asked if I was the only person with my last name.  What the hell?  How should I know?  I told her yes authoritatively, fearing she might turn me away if she found out I had no idea how many people with my last name were registered republicans.</p>
<p><strong>Let The Caucus Begin</strong></p>
<p>The first step was to find the table with people from my precinct.  I was given a name tag that told me my district, so I walked through 800 people to find it.  Once I found the table, I tried to listen to the various people there, hoping I could learn something about how caucuses work, since I had no idea.</p>
<p>Unfortunately, nobody else had any idea either.  My precinct leader didn't know what the hell she was doing, and said so.  I set about figuring out who the other Ron Paul supporters were.  This was easy.  Everyone fell into one of two categories: "old, fat people" and "kids that looked younger than 18".  Unsurprisingly, the folks in the second category were the Ron Paul folks.  One of them had a Ron Paul pamphlet from the rally a few days earlier.  Another had what appeared to be a Ron Paul CD.  I have no idea what was on that disc.</p>
<p>In any case, here is what I learned about how Caucuses work.  Basically a precinct gets a certain number of "delegates" meant to represent that precinct.  The precinct has to pick the delegates, and then those delegates go off with other precinct delegates from the same district.  Districts get a certain number of delegates, they pick the delegates, and those delegates move up another level.  This continues through various levels until all of the candidates have dropped out except one, who gets the nomination by default and the delegates all stay home.</p>
<p>We had to write our names and phone numbers down on a sheet of paper, and then everyone in the precinct had to decide who the delegates would be.  Apparently the little instruction manual said something along the lines of "decide amongst yourselves" for advice on how to choose people, which meant nobody knew of a fair way to decide.  Our chair, who I will refer to as Female Skeletor, started by asking who wanted to be a delegate, then answered her own question by saying she did.  The only other Ron Paul guy in the group, who looked a Backstreet Boy (and will now be referred to as Lance Bass), expressed reservation about being a delegate (he wanted to be an alternate) but volunteered.  I did as well, cuz I had to repazent.</p>
<p>There were only two more people, so one of them volunteered to be the other delegate.  Female Skeletor's solution to the problem of picking who got to be delegates and who got to be alternate was quite elegant: draw names from a hat.  As everyone knows, random chance is what the political system runs on.  That's why we don't vote in elections, but rather flip a coin.  What?  We don't do that at all?  Oh.</p>
<p>Eventually we convinced Female Skeletor she was stupid and decided to vote for who should become the delegates.  Unfortunately, there were only 5 people in the group, which meant Fifth Guy got to decide who would be the delegates and who would be the alternates.  Female Skeletor asked us to declare who we were supporting so Fifth Guy could make his choice.  Lance Bass and I declared Ron Paul, so Female Skeletor and Other Lady declared Romney.  Fifth Guy asked who Ron Paul was, so we handed him Lance Bass's info sheet.  He said Ron Paul looked interesting, but he wasn't sure.  I asked him what he thought of the war, and he said he wants us out of Iraq.  I said so does Ron Paul.  He voted for me as a delegate.</p>
<p>Well that was easy.  All I have to do is ask these people what they think of the war, and when they say it sucks I tell them Ron Paul wants us out.  Bang, I get a Ron Paul convert.  Easy-peasy.  I tried my luck on Skeletor, who explained that if we weren't in Iraq "all of them would be over here converting us all to Muslim and killing everyone else".  I quickly gave up on that plan.</p>
<p>In the end, Skeletor and I became the delegates, with Lance and Other Lady as alternates.</p>
<p>Not long after I had been chosen as a delegate, a few more people from our precinct decided to show up.  Everyone was chatting and waiting to be told what we were supposed to do next.  I was talking to Lance Bass, and suddenly Female Skeletor came up to me and told me that one of the guys who got here late (Late Guy) really wanted to be a delegate, so she crossed me off and put him on instead.  "Do you mind?" she asked.</p>
<p>Um.  Yeah, I kinda mind.  I asked Late Guy who he supported and he said Romney.  There's a shocker.  I explained that I had won the vote fair and square, and if she wants Late Guy on the list, she should cross herself off to put him on.  I got a dirty look for this, because apparently my suggestion is downright CRAZY.</p>
<p>While we were waiting, some guy came on over the microphone, and asked us who hadn't yet voted in the straw poll (an informal poll that gets used by the media as though it was a vote).  Everyone raised their hand.  He went on to explain that there were 700 people in the room, and they had started the night with about 800 straw poll sheets and they were all filled out now.  Awesome.</p>
<p><strong>The Next Level</strong></p>
<p>In any case, eventually everyone who had not become a precinct delegate left, leaving only the delegates and alternates.  Once again, we had to "decide amongst ourselves" who would become our district delegates.  The district got 3 delegates and 3 alternates.    There were a total of ten precinct delegates around to vote on this round.  Once again, nobody knew what voting mechanism we should use to decide which three of the ten would become delegates and which three would become alternates.  Once again, Female Skeletor suggested drawing from a hat and was ignored.  Once again, everyone was told to reveal who they supported.  Three of the ten (myself and Lance included) were Ron Paul supporters, while the other seven were for Romney (McCain was not a crowd favorite).  The third Ron Paul guy suggested that, since there were 3 delegates that needed to be chosen and one-third of the folks were in favor of Paul, one delegate should be a Ron Paul person and the other two should be for Romney.  This seemed fair, but the Romney folks would have none of it.</p>
<p>Instead, this is the system they designed: everyone would vote for their top 3 delegates.  Then we'd total everyones votes up.  The three most popular people would become delegates, and the next three would become alternates.  </p>
<p>I explained that this system was stupid.  All the Romney folks had to do was pick the same 3 people to vote for and they'd obviously get all three delegates.  That would leave the district as 100% represented with Romney supporters, even though a third of us were Paul fans.</p>
<p>A Romney supporter told me that's not true.  They may wind up splitting the vote and it would work in our favor. I explained that if they split the vote, they're idiots, because all they have to do is decide on the same three people and they get all three delegates.  I asked why they WOULDN'T do that.  Her response was "I dunno."</p>
<p>Despite our protest, the Romney people then immediately huddled up together and whispered about who they were going to vote for as delegates.  Shocking.  Since there were only 3 Ron Paul people, we all voted for the same three people.</p>
<p>We stood there shaking our heads in anger as the votes were tallied up, waiting to inevitably be told that none of us were going to be delegates.  But then something interesting happened: the Romney folks DID actually split their votes.  Everyone voted for themselves and the people from their precinct, one Romney person threw a single vote in the direction of a Ron Paul supporter (probably by accident), which was exactly the number needed to put one Ron Paul supporter in the top three.</p>
<p>Me.</p>
<p><strong>The Reluctant Delegate</strong></p>
<p>I couldn't believe it.  I had stood there and explained to these people how they could secure all three delegates, and then they failed to do so anyway.  Apparently, Romney supporters are really, really bad at math.  After the Romney folks wiped their look of shock off their faces, one of them smugly cracked "not such a stupid way to vote now, is it?  You got your way after all."</p>
<p>"Actually," I explained, "it was.  The stupidness of the system is unchanged by the fact that you all failed to use it strategically."  The two other Ron Paul guys told me to shut the hell up, since we won.  So much for an interest in fairness.  It's fair enough if we win, right?  Assholes.</p>
<p>Once all of the decisions had been made, the gloves came off.  Literally.  All of the Romney folks pulled folded-up red foam baseball mitts out of their jackets and began waving them around.  "Mitt '08" they said.  They had been hiding them all night, probably so that McCain supporters wouldn't realize they supported Mitt and do exactly to them what they tried to do to us.  It provides me with infinite satisfaction to know that their boy dropped out of the race two days later.  Just thinking of each of them throwing their foam mitts in the trash brings me great joy.</p>
<p>They then had to collect money from each of the new delegates.  Fifteen freaking dollars.  You hear that, Ron Paul?  You owe me fifteen bucks.  Fifteen bucks worth of gold, in fact, since you're such a big fan.</p>
<p>Given the fact that the Romney folks had tried to exclude me twice after finding out I was there for Ron Paul, I felt the need to stick around until the yellow sheet with my name next to the words "State Delegate" was sealed inside a manila envelope and handed to the caucus organizer, so I didn't get to go home for quite some time.</p>
<p>I'm in a very weird position now.  I now have to go to the next caucus on March 6th and express my support for Ron Paul, even though I very well might not vote for him in the general election.  I have to go convince a bunch of religious zealots that he's a good candidate for them because he is pro-life, even though I am not.  I feel compelled to continue, not for my own sake, but because I feel like I am representing other people who now are relying on me to go support Ron Paul.  My real motivator for not wanting to just give up is that those Romney jerks want me to give up.</p>
<p>I barely even understand the caucus system, but I'm my district's lone Ron Paul representative.  The guy is still way better than McCain, but I'm nowhere near as passionate about him as I once was.  Yet, the people I am representing ARE that passionate about him, so I feel compelled to feign the same level of excitement.  A small part of me wishes he would drop out and run as a third-party candidate, just so I don't have to go to the next caucus and deal with this crap again.</p>
<p><strong>Statistical Summary</strong></p>
<p>Here are the key statistics from these events.</p>
<ul>
<li>Number of times I thought to myself "what the fuck am I doing with these people?":<i> 5</i></li>
<li>Number of times I was called naive for supporting Ron Paul:<i> 2</i></li>
<li>Number of black people at caucus:<i> 1</i></li>
<li>Number of McCain supporters encountered the entire night:<i> 1</i></li>
<li>Number of times someone referred to the democratic front runners as "Hitlery and Osama":<i> 4</i></li>
<li>Number of times it was said by a fellow Ron Paul supporter, making me feel embarrassed:<i> 4</i></li>
<li>Number of times the word 'faith' was mentioned as an important reason to support Romney:<i> 6</i></li>
<li>Number of times I was stunned into silence by a stupid claim from a Romney supporter:<i> 3</i></li>
<li>Number of times Romney supporters tried to exclude me from the process:<i> 2</i></li>
<li>Number of times they failed:<i> 2</i></li>
<li>Number of Ron Paul converts I won over:<i> 1</i></li>
<li>Number of votes it took to make me a district delegate:<i> 1</i></li>
<li>Number of votes it took to make me a state delegate:<i> 4</i></li>
<li>Confidence level, on a scale from 1 to 10, in Caucuses:<i> 0</i></li>
<li>Number of hours I expected the caucus to take: <i>2</i></li>
<li>Number of hours it actually took: <i>7</i></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.nomachetejuggling.com/2008/02/08/my-first-caucus-the-tale-of-the-reluctant-delegate/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Changing Logging Behavior of Rails via Extensions</title>
		<link>http://www.nomachetejuggling.com/2008/02/01/changing-logging-behavior-of-rails-via-extensions/</link>
		<comments>http://www.nomachetejuggling.com/2008/02/01/changing-logging-behavior-of-rails-via-extensions/#comments</comments>
		<pubDate>Fri, 01 Feb 2008 18:46:41 +0000</pubDate>
		<dc:creator>Rod</dc:creator>
		
		<category><![CDATA[Computers]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.nomachetejuggling.com/2008/02/01/changing-behavior-of-rails-via-extensions/</guid>
		<description><![CDATA[One of the nicest things about Ruby is how well it supports metaprogramming.  You can dynamically, at runtime, change the behavior of any other class or module in the system, even private methods.  
When I was first learning Ruby, this seemed like a flaw, and while I still feel that this ability can [...]]]></description>
			<content:encoded><![CDATA[<p>One of the nicest things about Ruby is how well it supports metaprogramming.  You can dynamically, at runtime, change the behavior of any other class or module in the system, even private methods.  </p>
<p>When I was first learning Ruby, this seemed like a flaw, and while I still feel that this ability can be abused, it is definitely handy.</p>
<p>I'm going to explain a simple method of changing the behavior of part of Rails by a real-life example from work.</p>
<p>For a Ruby on Rails project I'm currently working on, we had a somewhat uncommon requirement.  We're dealing with a lot of data, which we store for other companies.  For various reasons, one of the concerns is that we may be subpoenaed and forced to provide all of our records for legal reasons.  In order to fully protect the identities of our customers, our system was designed around never actually storing any identifying information about our customers.  Instead, customers get a special code that identifies them, and we only have the ability to know the code, but we can't tie the code to any specific organization.  This may seem like a strange restriction, but for our application it was important.</p>
<p>This important aspect of the project had a number of implications for the design and implementation of the system, but in this post I'm only going to talk about one of them.  IP addresses, when recorded along with the time that an IP address accessed the system, could be used to make educated guesses about the companies using the system.  While the system itself does not record IP addresses or timestamps for hits, the web servers themselves do.  Modifying Apache not to log this kind of information was trivial, but one glaring issue remained.</p>
<p>In production mode, when an error occurs in the system, a log entry is created in production.log, which tries to provide details that the developers can use to figure out why the error occured.  This log contains a stacktrace, some time information, and various other pieces of data that can be helpful in debugging a critical issue.  It also logs the IP address of the user that generated the request that resulted in an error, like so:</p>
<pre>
Processing PostsController#some_action (for 127.0.0.1 at 2008-01-24 10:23:59) [POST]
  Session ID: b8f0b05d77fc4a5efdc04cf809f810d4
  Parameters: {}
</pre>
<p>The problem here is that the IP address is logged , and there is no way to change that via a configuration option.  I can turn logging off entirely, but I'd like to keep the error information in the event that the system actually does have a bug in it.</p>
<p>Luckily, the design of Ruby allows us to actually override this behavior relatively easily, and I'm going to explain how.</p>
<p><strong>Step 1: Figure Out What You Want To Change</strong></p>
<p>For this problem, figuring out what needed to be modified was relatively easy.  I was able to simply grep for "Processsing " inside of /usr/lib/ruby/gems/1.8/gems to find the file that was responsible for printing this line to the log.  It turns out that it was the base.rb file inside of action_controller.  Opening this file and searching revealed this method:</p>
<pre class="ruby"><span style="color:#9966CC; font-weight:bold;">def</span> log_processing
  <span style="color:#9966CC; font-weight:bold;">if</span> logger &amp;&amp; logger.<span style="color:#9900CC;">info</span>?
    logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;<span style="color:#000099;">\n</span><span style="color:#000099;">\n</span>Processing #{controller_class_name}<span style="color:#000099;">\#</span>#{action_name} (for #{request_origin}) [#{request.method.to_s.upcase}]&quot;</span>
    logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;  Session ID: #{@_session.session_id}&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> @_session <span style="color:#9966CC; font-weight:bold;">and</span> @_session.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>:session_id<span style="color:#006600; font-weight:bold;">&#41;</span>
    logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;  Parameters: #{respond_to?(:filter_parameters) ? filter_parameters(params).inspect : params.inspect}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre>
<p>This was a private method on the Base class inside of the ActionController module.  The rest of the process is quite easy.</p>
<p><strong>Step 2: Write The Override</strong></p>
<p>To override something, you simply define a new method as though it never existed before.  These get qualified in the same as defining any method on a class or a module.  Here is what mine looked like:</p>
<pre class="ruby"><span style="color:#9966CC; font-weight:bold;">module</span> ActionController
  <span style="color:#9966CC; font-weight:bold;">class</span> Base
    private
    <span style="color:#9966CC; font-weight:bold;">def</span> log_processing
      <span style="color:#9966CC; font-weight:bold;">if</span> logger &amp;&amp; logger.<span style="color:#9900CC;">info</span>?
        logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;<span style="color:#000099;">\n</span><span style="color:#000099;">\n</span>Processing #{controller_class_name}<span style="color:#000099;">\#</span>#{action_name} (for [FILTERED]) [#{request.method.to_s.upcase}]&quot;</span>
        logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;  Session ID: #{@_session.session_id}&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> @_session <span style="color:#9966CC; font-weight:bold;">and</span> @_session.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>:session_id<span style="color:#006600; font-weight:bold;">&#41;</span>
        logger.<span style="color:#9900CC;">info</span> <span style="color:#996600;">&quot;  Parameters: #{respond_to?(:filter_parameters) ? filter_parameters(params).inspect : params.inspect}&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre>
<p>As you can see, I am simply defining a method called "log_processing" on the Base class inside the ActionController module.  When Ruby interprets the above code, it will define this method, overwriting the method if it already exists.  All I did was change the IP address to say that it was filtered.  Note that even though this method is private, I am still able to do this painlessly.</p>
<p>The next step is to simply get Rails to run over this code and overwrite the existing log_processing method.</p>
<p><strong>Step 3: Making It Load</strong></p>
<p>There are a lot of ways you can do this.  The ideal way is to create a plugin in vendor/plugins that contains this code.  Rails will automatically run over the code at the correct time.  This is a slightly more complex approach than I'd like to cover here, however, so we're going to just try and get this into the system as quickly as possible.</p>
<p>I've found that once you start doing this sort of stuff, you like to have a single place to keep all the behavior modifications you are using.  Sometimes you'd like to simply add a method to a class, or change part of Rails.  These changes are basically all unrelated, except that they are important for your application.  For this reason, I like to keep them all together in a single file so that it's easy to see what has been changed/added.  Obviously if you wind up making a lot of changes, you should make a plugin instead, particularly if the changes might be useful in other rails apps.</p>
<p>Save the above code into a file called "extensions.rb" inside of the "extras" directory under my rails project directory.</p>
<p>Then, go into your environment.rb file and add this line to the bottom:</p>
<pre class="ruby">&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> File.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, 'extras', 'extensions'<span style="color:#006600; font-weight:bold;">&#41;</span></pre>
<p>The reason I suggest the bottom of the file (after the Rails::Initializer.run) is that you want to make sure all of the rails libraries are loaded first, otherwise they will overwrite YOUR method, instead of the other way around.</p>
<p>That's it.  Now, whenever you run rails (even in script/console), your changes will be reflected.  This successfully causes the error log to leave the IP address out of what is recorded.  </p>
<p>This is not something that should be done a lot in your application.  Changing the behavior of core parts of rails will likely confuse other developers on your team.  That's why, if this method is employed, I believe you should keep these changes to a minimum, and keep them all in one place.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomachetejuggling.com/2008/02/01/changing-logging-behavior-of-rails-via-extensions/feed/</wfw:commentRss>
		</item>
		<item>
		<title>My First eBay Scam Experience</title>
		<link>http://www.nomachetejuggling.com/2008/01/16/my-first-ebay-scam/</link>
		<comments>http://www.nomachetejuggling.com/2008/01/16/my-first-ebay-scam/#comments</comments>
		<pubDate>Wed, 16 Jan 2008 20:20:32 +0000</pubDate>
		<dc:creator>Rod</dc:creator>
		
		<category><![CDATA[Computers]]></category>

		<category><![CDATA[Life]]></category>

		<category><![CDATA[Security]]></category>

		<category><![CDATA[ebay]]></category>

		<category><![CDATA[internet]]></category>

		<guid isPermaLink="false">http://www.nomachetejuggling.com/2008/01/16/my-first-ebay-scam/</guid>
		<description><![CDATA[I use a projector for my home theater system.  I recently upgraded to a Hi-Def projector, leaving me with an old, fully-functional InFocus X2 projector.  Projectors are pretty expensive, so I wanted to get some money for it rather than just throw it away or give it to someone else.  Thus, I [...]]]></description>
			<content:encoded><![CDATA[<p>I use a projector for my home theater system.  I recently upgraded to a Hi-Def projector, leaving me with an old, fully-functional InFocus X2 projector.  Projectors are pretty expensive, so I wanted to get some money for it rather than just throw it away or give it to someone else.  Thus, I decided to sell the InFocus projector on eBay.  This was my first time selling something on eBay, and, given how it went, likely my last.</p>
<p><strong>Making A Sale</strong></p>
<p>The projector went up on eBay on Sunday night.  On Tuesday, a user named 'hakim199' had used the Buy It Now option to purchase it for $300.  The shipping address on that user account was for a hospital in Abu Dhabi.  I had not planned on selling the projector internationally, but I didn't particularly care.  I e-mailed the user to say thanks for buying the thing and I'll send the projector as soon as I get payment.</p>
<p>Shortly after this I received an e-mail from someone named "Mandy Pat" which said this:</p>
<p><span id="more-116"></span></p>
<blockquote><p>
<strong>From</strong>: "Mandy Pat" (omanpatXX@yahoo.com)<br />
<strong>To</strong>: Rod</p>
<p>Hello Seller, </p>
<p> Am very happy to be the winning bidder of your lovely item which i just made an immediate payment for now as requested by eBay and more so i added extra $200 for the shipping of the item to my son that got married last week in Nigeria but due to my nature of work here am unable to get there so that is why am buying this item for him as a wedding gift from father to son and he called me last night about this item and i told him he will soon be receiving it and i don't want you to turn me to a lier in his face....So make sure you get the item shipped out immediately you receive the PayPal payment confirmation from PayPal and get back to either i or paypal with the shipment tracking number for them to verify and confirm in order for them to credit your PayPal account immediately.</p>
<p>Thanks and get it shipped out through USPS GLOBAL EXPRESS MAIL SERVICE[EMS] and here is the shipping address once again.
</p></blockquote>
<p>I believe that entire first paragraph is a single sentence.  Impressive work.  So, this person wanted me to rush the order, and they provided a shipping address in Nigeria (which was different from the Abu Dhabi address on file).  This seemed rather fishy to me, so I e-mailed eBay to ask about it.  </p>
<p>Before I could even hit send, I had an e-mail in my inbox, from eBay, which said this:</p>
<blockquote style="background-color: #fffff8; border-color: #ffff00"><p>
<strong>From</strong>: ended@ebay.com<br />
<strong>To</strong>: Rod</p>
<p>The results of the following listing(s) have been cancelled due to bidding activity that took place without the account owner's authorization:</p>
<p>170185412579 Infocus X2 Projector with Ceiling Mount</p>
<p>We have canceled the listing(s) to maintain the integrity of the eBay site, your account, and the bidder?s account that was accessed. We are working to restore the bidding account to its rightful owner, and we are working with the account owner to prevent any additional unauthorized activity. Since the account owner did not initiate these bids, all fees resulting from the listings in question will be credited to your account within 7 days. If you do not see the credits posted to your account after 7 days, please feel free to contact us through ?Contact Us? in our Help section.</p>
<p>Unfortunately, it is not possible for us to automatically relist these items for you. Instead, to relist these items you will need to start from the beginning of the listing process, either through the "Sell Your Item" process or through your third party listing service. We know that this is an inconvenience and we apologize for the negative impact it may cause you. We are working on tools to allow you to relist your items without starting from the beginning, but they are not available at this time.
</p></blockquote>
<p>This mostly irritated me, as I saw no reason why eBay shouldn't automatically relist my item.  Nonetheless, this looked like a legitimate e-mail from eBay (the address was right) and it addressed me by my real name (not shown), so I relisted my item.  A day later, another user (who was interested in the original auction and posted a question to it) in Italy purchased the projector.  At first I was concerned that this was all part of a large scam, but a great deal of investigation (plus the added input from three coworkers) helped me decide that the guy from Italy was legit, so I decided I would send it to him.  He also deposited the money into my PayPal account, so it seemed quite real.</p>
<p>Not long after this, I received another e-mail from eBay:</p>
<blockquote style="background-color: #fffff8; border-color: #ffff00"><p>
<strong>From</strong>: "aw-confirm@eBay.com" (ebayresolutioncenter@mail2helpdesk.com)<br />
<strong>To</strong>: Rod</p>
<p>This message was originated from the  eBay and PayPal team. We appologise for the cancellation of your eBay item, it was formally canceled due an Error 908 on the eBay Data Base.The  eBay & PayPal team has both agreed to erase the cancellation and re-activate the item from the eBay Data Base. We have confirmed that  (Mandy Pat) is the rightful owner of the eBay account,which was accessed by an unauthorized person. So we gladly urge you to complete the transaction with him/her so as to receive your funds into your PayPal account.</p>
<p>We have been informed by PayPal Authority that the money will not be transfer into your PayPal account until they confirm the shipment details of the item. You are request to proceed with the shipment of the item within the next 12 - 24 Hours and get back to PayPal with the shipment tracking number for shipment verification so as to receive the funds into your PayPal account. Please Do not in anyway send the reference/tracking number of the item to the BUYER for the safety of your money.
</p></blockquote>
<p>Maybe I should have noticed that appologise was spelled wrong, but I didn't. Besides, eBay spelled "cancelled" in two different ways in their email. </p>
<p>The e-mail used the same layout and html template as the other e-mails from eBay.  The only real difference was that the light gray name that it was addressed to was not my name any more, but "eBay Community Member".  Considering this was gray and in the smallest font in the e-mail, I didn't notice it.  I did, however, check the "from" address and noticed that, while the account NAME was "aw-confirm@eBay.com", the actual e-mail address was "ebayresolutioncenter@mail2helpdesk.com"</p>
<p>Clearly this was not legitimate.  Not long after this, I got this e-mail from service@paypal.com:</p>
<blockquote style="background-color: #f8fff8; border-color: #00ff00"><p>
<strong>From</strong>: "service@paypal.com" (paypal.consultants@accountantemail.com)<br />
<strong>To</strong>: Rod</p>
<p>You ought to have shipped the item to the given address in Nigeria by now,You can now forward us the shipping verification(Tracking Number), so that we can credit your PayPal account with the total sum of $500.00,We hope to hear from you soon.<br />
Thank you, PayPal Customer care</p>
<p>We are very sorry for the inconveniences this may cause.Please bear with us, this new measure is taken to secure our client's interest against lost of item or non payment eBayer. Send shipment details to us through this mail paypal.consultants@accountantemail.com and our customer service care will attend to you. As soon as you send us the shipment's tracking number to us for security purposes and the safety of the buyer and the seller,the money will be credited to your account.</p>
<p>Note: Please reply this mail between the next 12 hours.Failure to respond to this mail may leads to Limitation of your PayPal account.
</p></blockquote>
<p>Gosh, I don't want a Limitation of my account.  Checking this e-mail address revealed it was actually from "paypal.consultants@accountantemail.com".  Okay, I get it.  Very cute.  This is a good ol' fashioned Nigerian scam.  You make me think that my money is being held by PayPal, I ship my item, I tell the buyer, then I get no money and you get my projector.  Nice work. If I wasn't a technical person, I probably would have fallen for this.  The deluge of e-mails I got from PayPal and eBay surrounding these TWO purchases of my item served to confuse me, especially considering I was new to this process.</p>
<p>I figured I would just ignore the scammer and send the package on its merry way to Italy.  </p>
<p>But the scammer didn't stop there.</p>
<p><strong>Turning The Tables</strong></p>
<p>I get another e-mail from "Mandy".</p>
<blockquote><p>
<strong>From</strong>: "Mandy Pat" (omanpatXX@yahoo.com)<br />
<strong>To</strong>: Rod</p>
<p>Hello Mate,<br />
 The payment has already been made to your PayPal account and i even add extra $200 for the shipping of the item to my son in Nigeria as i know is an international shipment and i hope you should have been contacted by PayPal by now with the payment confirmation mail.....So make sure you get the item shipped out now and get back to PayPal with the shipment tracking number so that they can release the payment to your account immediately.</p>
<p>Thanks and make sure you get it shipped out through Usps Global Express Mail Service Ems.
</p></blockquote>
<p>Now, my gut reaction here is to simply say "Fuck off, scammer asshole." and attach a picture of my balls to the e-mail, but I really don't want to engage this person any further.  I figured if I "outed" him, I may have to deal with him for a while, so I decided to play along and explain "what happened" in a way that would get him to realize that this scam simply wasn't going to pan out and he should move on.</p>
<blockquote style="background-color: #f8f8ff; border-color: #0000ff"><p>
<strong>From</strong>: Rod<br />
<strong>To</strong>: "Mandy Pat" (omanpatXX@yahoo.com)</p>
<p>I have bad news for you.  Shortly after you purchased the item and I responded with the question below, eBay contacted me and told me the purchase originating from your account was fraudulent and the transaction was cancelled.  eBay told me I should relist my item, so I did, and it was purchased by another member.  Shortly after THAT, eBay informed me that they investigated your account and determined that it was NOT fradulent after all, and that I should pay you.</p>
<p>Unfortunately, this other member has already paid me, and I've shipped it to him.  I apologize that eBay messed up this transaction so much. I think you should withdraw your payment to me and keep searching.</p>
<p>Good luck.
</p></blockquote>
<p>Now, obviously the second message saying the account was alright was not actually from eBay, but this scammer thought that I thought it was, so I had to play along if I wanted to avoid backing him into a corner and having him do something obnoxious with my e-mail address (such as, continue e-mailing it).</p>
<p>I figured this was the end of it, and that he would simply give up and go try and scam someone else.</p>
<p>I was wrong.  Mandy Pat was pissed.</p>
<blockquote><p>
<strong>From</strong>: "Mandy Pat" (omanpatXX@yahoo.com)<br />
<strong>To</strong>: Rod</p>
<p>Hello Rod,<br />
 What the fuck are you telling me after i made the immediate payment for you and your money has been deducted from my PayPal account and i even add extra $200 for the shipping cost for you and i got a confirmation mail from paypal that they have send you the payment confirmation mail....That they are still waiting for your response......They even inform me that they cannot refund any money for me again since it has been deducted from my account....So make sure you buy the item for my son and get it shipped out immediately.</p>
<p>Thanks and get back to me with the tracking number.
</p></blockquote>
<p>Well, fine, if you're going to be a cock about it, maybe I will send you a picture of my balls after all.  Before I could even reply, I got an e-mail from "service@paypal.com" (but not really).  The subject was "PAYPAL LEGAL ACTION".  Oh noes!</p>
<blockquote style="background-color: #f8fff8; border-color: #00ff00"><p>
<strong>From</strong>: "service@paypal.com" (paypal.consultants@accountantemail.com)<br />
<strong>To</strong>: Rod<br />
<strong>Subject</strong>: PAYPAL LEGAL ACTION</p>
<p>    It is important we know the status of the item bought otherwise, legal  action may be taken against you since you have not replied to the confirmation of payment made to your account by Mandy Pat   over time.</p>
<p>We believed you entered into bidding agreement by requesting money through PayPal,and by non response to the payment confirmation made to your account you have violated the eBay and PayPal agreement, because the payment has been made by the buyer and we have already contacted you with the payment confirmation mail, all you need to do is to get the item shipped and send the tracking number to us for shipment verification, so as to get the money deposited into your account. However the buyer has already contacted us in other to make report about your non response.We are ensuring to make PayPal a safer place, therefore we need to set confidence on our users. Although, an error occurred while processing your payment as an error came upon our transaction machine in which we sent you two transaction payments but this has been taken care of and everything is now in place. We request for the Scanned Receipt and the Tracking Number to prove postage of the item in less than 24hours and we will fund the money into your account or face the consequences of Legal action. This legal action might results to blockage of your PayPal account temporarily or permanently.<br />
This is done in other to protect both the seller and buyer.
</p></blockquote>
<p>Wow, what an asshole.  The guy didn't back down even after I told him his projector had been sent, so clearly he still wanted to see what he could get out of me.  I mean, he basically told me to buy a new projector and send it to his kid in Nigeria for $500, so he obviously thinks I'm a special kind of moron.</p>
<p>This would be like trying to steal my wallet from my pocket, and then I catch you doing it and grab your wrist.  Instead of saying "crap" and running away, imagine saying "Hello sir, I'm a Wallet Inspector with the FBI.  I need to verify that your wallet is in Wallet Compliance."  I mean, honestly - you lost.  It's over.  Walk away with your dignity, don't keep trying to run your game on me.</p>
<p>At this point in the day, I had been keeping my co-workers updated about this whole situation.  I asked them what they thought I should do about this, and the answer was unanimous: Scam the Scammer.</p>
<p>The goal was to see if I could try to extract his bank account information from him, in the same way that Nigerian scammers traditionally do.  The first suggestion was to explain I'd like to help him out, but my uncle (who is the Prince of America) recently died and left me a lot of money, so I need his account number to smuggle the money through, and I'll give him a cut.  </p>
<p>In the end, I took a slightly more subtle approach:</p>
<blockquote style="background-color: #f8f8ff; border-color: #0000ff"><p>
<strong>From</strong>: Rod<br />
<strong>To</strong>: "Mandy Pat" (omanpatXX@yahoo.com)</p>
<p>Oh my goodness!</p>
<p>Well, I'm very sorry you are so upset about this.  I wish you wouldn't use that kind of language with me, but I can forgive it because I can tell you are very upset.</p>
<p>I would be, too.  You have to understand, eBay told me that they cancelled the transaction and delisted my item, so I no longer thought it was a legitimate sale.</p>
<p>I got an e-mail from PayPal telling me that they may take legal action against me a little while ago.  I definitely don't want to be sued because of this.  It is unfortunate that PayPal won't return your money to you, I figured they would just let you back out of the sale.</p>
<p>I'll tell you what.  If you tell PayPal that the item was received, you can release the funds to my account.  Give me your personal bank account number and I will wire that money back to you as soon as I get it, plus $100 for all of your trouble.  I don't want to go to jail, so I'm willing to pay more than $100 if you want.</p>
<p>I apologize for this inconvenience, and I hope we can work something out.
</p></blockquote>
<p>My co-workers and I couldn't help but wonder if Mandy, upon reading this, stood up in whatever internet cafe that scammers operate from and ask "Hey, is this anyone of you guys?  Did we get cross-threaded here or something?"</p>
<p>After many hours, I finally got another e-mail from Mandy Pat.  As you can imagine, he did not enjoy this plan.</p>
<blockquote><p>
<strong>From</strong>: "Mandy Pat" (omanpatXX@yahoo.com)<br />
<strong>To</strong>: Rod</p>
<p>Hello Rod,</p>
<p> What are u still telling me..........I should inform PayPal that the item has been received...when have not  received it and they cannot refund my money back for me unless  you send them the tracking number and they will credit your account.....Am not in the state presently....So i can even give you my personal bank account........What i want you to do now and i will even inform PayPal now.....I want you to send the money out to my son in Nigeria through Western Union Money Transfer and get back to PayPal with the MTCN code with the secret question and answer so that they can credit your account immediately...As am tired with all this ship....after i made the payment for you.
</p></blockquote>
<p>I can barely understand this incomprehensible babble, but it seems like he's buying the idea that I'm willing to send him money.  He is tired of his ship though.  Well so am I.  Now I just want him to go away and leave my e-mail address alone.</p>
<blockquote style="background-color: #f8f8ff; border-color: #0000ff"><p>
<strong>From</strong>: Rod<br />
<strong>To</strong>: "Mandy Pat" (omanpatXX@yahoo.com)</p>
<p>Pat!</p>
<p>I have great news!  I got an e-mail from the guy who purchased my<br />
projector, and he said he actually found a projector online for<br />
cheaper and bought that.  He asked if I wouldn't mind taking my<br />
projector back and giving him a refund.</p>
<p>I told him about our predicament, and he said he's happy to help.<br />
Rather than wait for him to get the package (it's still on it's way to<br />
him), then send it back to me, then wait for me to send it to your<br />
son, he's willing to send it directly to your son.  This will help it<br />
arrive in time for his wedding!</p>
<p>He said I can go ahead and give his information to you.  His name is<br />
Remus MacSuftin, and he lives in Ireland.  You can e-mail him at<br />
RemMacSufXX@yahoo.com and work out the details.</p>
<p>I'm so glad we could get this mess worked out!  Enjoy the projector!
</p></blockquote>
<p>I figured, if he sent me any more e-mails, I could tell him to just take it up with Remus.  By the way, I really did create the e-mail account (remmacsuf is F.U. Scammer backwards), but he never e-mailed it.  I guess he figured this effort was no longer worth his time.</p>
<p><strong>Lessons Learned</strong></p>
<p>I don't know if I'll be using eBay ever again.  I am told by friends you can specify that only confirmed shipping addresses can bid/buy eBay auctions, but I didn't see that option when I was setting up the auction originally.  Certainly this experience has made me hesitant to screw around with it again, particularly because people doing the Buy It Now option and then failing forces me to to relist the item, costing me approximately 6 bucks every time (eBay charges you for pictures, thumbnails, html, layouts, etc).  </p>
<p>Certainly I have two suggestions for improvement, one for eBay and one for Google.  eBay starts e-mails by addressing you by your real name, then explaining that they do that so you know the e-mail is legit.  That's handy, except that it's in gray rather than black text, and it's the smallest font in the e-mail.  More attention should be drawn to this.</p>
<p>More importantly, Google's gmail service does little to help the situation.  The "From" column uses the name someone gives for their e-mail address.  So if I send a message as from "Rod (email.address@domain.com)" it shows up as from "Rod".  When actually reading the e-mail, it still only shows "Rod" unless you specifically click to show details.  This allows someone to provide a name that resembles an e-mail address, and have it look to the recipient as though it was from that address.  This is so easy to fix, I don't honestly know why Google hasn't done it.  When displaying the "From", check to see if the name looks like an e-mail address.  If it does, and the name e-mail address domain is different from the actual e-mail address domain, color the message yellow or red and put some kind of warning on it that says it seems to be a forgery attempt.  Or, if the from name resembles an e-mail address, don't display it at all: instead display the actual address the message is from.  Granted, both the name and e-mail address in the From field can be forged, but at least this would help with scams like these.</p>
<p>As a final note, I forwarded nearly all of these scam e-mails to eBay, and I've e-mailed them with my concerns a number of times.  I still have not recieved any non-automated response.  eBay should probably make a larger effort to deal with this kind of thing, or eBay will simply become a place scammers try to scam each other.</p>
<p>If my mother, or someone else nontechnical, had tried to do this, I can't imagine them not being taken advantage of.  All of the fake e-mails looked legitimate (they used the same layouts and colors as PayPal and eBay) and, aside from some misspellings, seemed fine.  If a nontechnical person were to ask me for advice selling something online, I'd have to advice them to use craigslist instead and sell it locally.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomachetejuggling.com/2008/01/16/my-first-ebay-scam/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Craziest&#8230; Bookmarklet&#8230; Ever.</title>
		<link>http://www.nomachetejuggling.com/2007/11/06/craziest-bookmarklet-ever/</link>
		<comments>http://www.nomachetejuggling.com/2007/11/06/craziest-bookmarklet-ever/#comments</comments>
		<pubDate>Tue, 06 Nov 2007 23:42:56 +0000</pubDate>
		<dc:creator>Rod</dc:creator>
		
		<category><![CDATA[Computers]]></category>

		<category><![CDATA[Programming]]></category>

		<category><![CDATA[Security]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[firefox]]></category>

		<category><![CDATA[internet]]></category>

		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.nomachetejuggling.com/2007/11/06/craziest-bookmarklet-ever/</guid>
		<description><![CDATA[What Is This?
This is a bookmarklet that will allow you to store private sites a bookmark manager like Google Browser Sync.
What Does That Mean?
Google Browser Sync is a way of sharing browser data, like bookmarks, across all of the computers you use.  It's a Firefox browser extension, and it works like a charm.  [...]]]></description>
			<content:encoded><![CDATA[<p><strong>What Is This?</strong></p>
<p>This is a bookmarklet that will allow you to store private sites a bookmark manager like <a href="http://www.google.com/tools/firefox/browsersync/">Google Browser Sync.</a></p>
<p><strong>What Does That Mean?</strong></p>
<p>Google Browser Sync is a way of sharing browser data, like bookmarks, across all of the computers you use.  It's a Firefox browser extension, and it works like a charm.  The data is encrypted when transferred, and according to Google, the data is stored in Google's data center in a way that even Google employees can't see it.</p>
<p>Unfortunately, the extension code is (mostly) compiled, which makes it extremely difficult to verify that your browser data is actually stored in a way such that only you can decrypt it.  Of course, I like to trust Google (and I want to work there *HINT*), but the fact that I can't view the source code makes me nervous about using Browser Sync on my desktop machine, since I store URLs there that I don't want anyone seeing, such as private torrent tracker sites.  Er, I mean, uh, legal torrent, um, sites, er, with Linux distributions and, uh, creative-commons music.</p>
<p>What tinfoil-hat-wearing lunatics like myself need is way of storing bookmarks to super-private urls in a way so that the bookmark stored doesn't give away the actual url.</p>
<p><span id="more-114"></span></p>
<p><strong>How Does This Work?</strong></p>
<p>The short version is that, instead of storing the url to a Super-Private Site, you store a javascript bookmarklet.  This bookmarklet stores an encrypted version of the URL.  It asks you for your decryption key, decrypts the encrypted version of the URL, then loads the address bar with the decrypted URL.  The en/decryption algorithm being used in my implemention is the <a href="http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm">Tiny Encryption Algorithm</a>.</p>
<p>Of course, the real tricky bit is that I actually need a bookmarklet that will GENERATE these bookmarklets for me.  That's the bookmarklet I am providing.</p>
<p>Drag this link to your bookmarks:<br />
[<a href="javascript:/* TEA JavaScript Implementation Copyright Chris Veness: http://www.movable-type.co.uk/scripts/tea-block.html */ function TEAencrypt(plaintext, password) { if (plaintext.length == 0) return(''); var asciitext = escape(plaintext).replace(/%20/g,' '); var v = strToLongs(asciitext); if (v.length <= 1) v[1] = 0; var k = strToLongs(password.slice(0,16)); var n = v.length; var z = v[n-1], y = v[0], delta = 0x9E3779B9; var mx, e, q = Math.floor(6 + 52/n), sum = 0; while (q-- > 0) { sum += delta; e = sum>>>2 & 3; for (var p = 0; p < n; p++) { y = v[(p+1)%n]; mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z); z = v[p] += mx; } } var ciphertext = longsToStr(v); return escCtrlCh(ciphertext); } function TEAdecrypt(ciphertext, password) { if (ciphertext.length == 0) return(''); var v = strToLongs(unescCtrlCh(ciphertext)); var k = strToLongs(password.slice(0,16)); var n = v.length; var z = v[n-1], y = v[0], delta = 0x9E3779B9; var mx, e, q = Math.floor(6 + 52/n), sum = q*delta; while (sum != 0) { e = sum>>>2 & 3; for (var p = n-1; p >= 0; p--) { z = v[p>0 ? p-1 : n-1]; mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z); y = v[p] -= mx; } sum -= delta; } var plaintext = longsToStr(v); plaintext = plaintext.replace(/\0+$/,''); return unescape(plaintext); } function strToLongs(s) { var l = new Array(Math.ceil(s.length/4)); for (var i=0; i<l.length; i++) { l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) + (s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24); } return l; } function longsToStr(l) { var a = new Array(l.length); for (var i=0; i<l.length; i++) { a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF, l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF); } return a.join(''); } function escCtrlCh(str) { return str.replace(/[\0\t\n\v\f\r\xa0'%22!]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; }); } function unescCtrlCh(str) { return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); }); } input=window.location; key=prompt(%22Pick an encryption key (you must type this every time you load the bookmark)%22); sitename=window.document.title; encrypted=TEAencrypt(input,key); the_code=TEAencrypt.toSource() + TEAdecrypt.toSource() + strToLongs.toSource() + longsToStr.toSource()+ escCtrlCh.toSource() + unescCtrlCh.toSource(); the_code=the_code.replace(/\%22/g,%22'%22); document.write(%22Bookmark this link:<br/>[<a href=\%22javascript:%22+ the_code + %22; key=prompt('What is your decryption key?'); decrypted=TEAdecrypt('%22+ encrypted+%22', key); window.location=decrypted;\%22>%22+sitename+%22</a>]%22);">Encrypt-Bookmark This Page</a>]</p>
<p><strong>How Do I Use It?</strong></p>
<p>Once you've dragged the above bookmark into your bookmarks, all you have to do is click it whenever you're at a page you want to bookmark in an encrypted way.  It will prompt you for your encryption key.  Provide one and hit okay.  The page will be replaced by a page giving you A NEW BOOKMARKLET, which you can then drag to your bookmarks as well.</p>
<p>When you click THAT bookmarklet, you will be prompted for your decryption key.  Provide the same key as before, and your secret site will load.</p>
<p><strong>What Does The Code Look Like?</strong></p>
<pre class="javascript"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900; font-style: italic;">/*</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900; font-style: italic;">    TEA JavaScript Implementation Copyright Chris Veness:</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900; font-style: italic;">    http://www.movable-type.co.uk/scripts/tea-block.html</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900; font-style: italic;">*/</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> TEAencrypt<span style="color: #66cc66;">&#40;</span>plaintext, password<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>plaintext.<span style="color: #006600;">length</span> == <span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> asciitext = escape<span style="color: #66cc66;">&#40;</span>plaintext<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">replace</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066FF;">/%<span style="color: #CC0000;">20</span>/g</span>,<span style="color: #3366CC;">' '</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> v = strToLongs<span style="color: #66cc66;">&#40;</span>asciitext<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>v.<span style="color: #006600;">length</span> &lt;= <span style="color: #CC0000;">1</span><span style="color: #66cc66;">&#41;</span> v<span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #66cc66;">&#93;</span> = <span style="color: #CC0000;">0</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> k = strToLongs<span style="color: #66cc66;">&#40;</span>password.<span style="color: #006600;">slice</span><span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;">0</span>,<span style="color: #CC0000;">16</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> n = v.<span style="color: #006600;">length</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> z = v<span style="color: #66cc66;">&#91;</span>n<span style="color: #CC0000;">-1</span><span style="color: #66cc66;">&#93;</span>, y = v<span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#93;</span>, delta = 0x9E3779B9;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> mx, e, q = Math.<span style="color: #006600;">floor</span><span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;">6</span> + <span style="color: #CC0000;">52</span>/n<span style="color: #66cc66;">&#41;</span>, sum = <span style="color: #CC0000;">0</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #66cc66;">&#40;</span>q-- &gt; <span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    sum += delta;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    e = sum&gt;&gt;&gt;<span style="color: #CC0000;">2</span> &amp; <span style="color: #CC0000;">3</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> p = <span style="color: #CC0000;">0</span>; p &lt; n; p++<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">      y = v<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>p<span style="color: #CC0000;">+1</span><span style="color: #66cc66;">&#41;</span>%n<span style="color: #66cc66;">&#93;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">      mx = <span style="color: #66cc66;">&#40;</span>z&gt;&gt;&gt;<span style="color: #CC0000;">5</span> ^ y&lt;&lt;<span style="color: #CC0000;">2</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #66cc66;">&#40;</span>y&gt;&gt;&gt;<span style="color: #CC0000;">3</span> ^ z&lt;&lt;<span style="color: #CC0000;">4</span><span style="color: #66cc66;">&#41;</span> ^ <span style="color: #66cc66;">&#40;</span>sum^y<span style="color: #66cc66;">&#41;</span> + <span style="color: #66cc66;">&#40;</span>k<span style="color: #66cc66;">&#91;</span>p&amp;<span style="color: #CC0000;">3</span> ^ e<span style="color: #66cc66;">&#93;</span> ^ z<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">      z = v<span style="color: #66cc66;">&#91;</span>p<span style="color: #66cc66;">&#93;</span> += mx;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> ciphertext = longsToStr<span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">return</span> escCtrlCh<span style="color: #66cc66;">&#40;</span>ciphertext<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> TEAdecrypt<span style="color: #66cc66;">&#40;</span>ciphertext, password<span style="color: #66cc66;">&#41;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>ciphertext.<span style="color: #006600;">length</span> == <span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #000066; font-weight: bold;">return</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> v = strToLongs<span style="color: #66cc66;">&#40;</span>unescCtrlCh<span style="color: #66cc66;">&#40;</span>ciphertext<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> k = strToLongs<span style="color: #66cc66;">&#40;</span>password.<span style="color: #006600;">slice</span><span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;">0</span>,<span style="color: #CC0000;">16</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> n = v.<span style="color: #006600;">length</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> z = v<span style="color: #66cc66;">&#91;</span>n<span style="color: #CC0000;">-1</span><span style="color: #66cc66;">&#93;</span>, y = v<span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#93;</span>, delta = 0x9E3779B9;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> mx, e, q = Math.<span style="color: #006600;">floor</span><span style="color: #66cc66;">&#40;</span><span style="color: #CC0000;">6</span> + <span style="color: #CC0000;">52</span>/n<span style="color: #66cc66;">&#41;</span>, sum = q*delta;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">while</span> <span style="color: #66cc66;">&#40;</span>sum != <span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    e = sum&gt;&gt;&gt;<span style="color: #CC0000;">2</span> &amp; <span style="color: #CC0000;">3</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> p = n<span style="color: #CC0000;">-1</span>; p &gt;= <span style="color: #CC0000;">0</span>; p--<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">      z = v<span style="color: #66cc66;">&#91;</span>p&gt;<span style="color: #CC0000;">0</span> ? p<span style="color: #CC0000;">-1</span> : n<span style="color: #CC0000;">-1</span><span style="color: #66cc66;">&#93;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">      mx = <span style="color: #66cc66;">&#40;</span>z&gt;&gt;&gt;<span style="color: #CC0000;">5</span> ^ y&lt;&lt;<span style="color: #CC0000;">2</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #66cc66;">&#40;</span>y&gt;&gt;&gt;<span style="color: #CC0000;">3</span> ^ z&lt;&lt;<span style="color: #CC0000;">4</span><span style="color: #66cc66;">&#41;</span> ^ <span style="color: #66cc66;">&#40;</span>sum^y<span style="color: #66cc66;">&#41;</span> + <span style="color: #66cc66;">&#40;</span>k<span style="color: #66cc66;">&#91;</span>p&amp;<span style="color: #CC0000;">3</span> ^ e<span style="color: #66cc66;">&#93;</span> ^ z<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">      y = v<span style="color: #66cc66;">&#91;</span>p<span style="color: #66cc66;">&#93;</span> -= mx;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    sum -= delta;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> plaintext = longsToStr<span style="color: #66cc66;">&#40;</span>v<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  plaintext = plaintext.<span style="color: #006600;">replace</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066FF;">/\<span style="color: #CC0000;">0</span>+$/</span>,<span style="color: #3366CC;">''</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">return</span> unescape<span style="color: #66cc66;">&#40;</span>plaintext<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> strToLongs<span style="color: #66cc66;">&#40;</span>s<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> l = <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #66cc66;">&#40;</span>Math.<span style="color: #006600;">ceil</span><span style="color: #66cc66;">&#40;</span>s.<span style="color: #006600;">length</span>/<span style="color: #CC0000;">4</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i=<span style="color: #CC0000;">0</span>; i&lt;l.<span style="color: #006600;">length</span>; i++<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    l<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> = s.<span style="color: #006600;">charCodeAt</span><span style="color: #66cc66;">&#40;</span>i*<span style="color: #CC0000;">4</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #66cc66;">&#40;</span>s.<span style="color: #006600;">charCodeAt</span><span style="color: #66cc66;">&#40;</span>i*<span style="color: #CC0000;">4</span><span style="color: #CC0000;">+1</span><span style="color: #66cc66;">&#41;</span>&lt;&lt;<span style="color: #CC0000;">8</span><span style="color: #66cc66;">&#41;</span> +</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">         <span style="color: #66cc66;">&#40;</span>s.<span style="color: #006600;">charCodeAt</span><span style="color: #66cc66;">&#40;</span>i*<span style="color: #CC0000;">4</span><span style="color: #CC0000;">+2</span><span style="color: #66cc66;">&#41;</span>&lt;&lt;<span style="color: #CC0000;">16</span><span style="color: #66cc66;">&#41;</span> + <span style="color: #66cc66;">&#40;</span>s.<span style="color: #006600;">charCodeAt</span><span style="color: #66cc66;">&#40;</span>i*<span style="color: #CC0000;">4</span><span style="color: #CC0000;">+3</span><span style="color: #66cc66;">&#41;</span>&lt;&lt;<span style="color: #CC0000;">24</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">return</span> l;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> longsToStr<span style="color: #66cc66;">&#40;</span>l<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #003366; font-weight: bold;">var</span> a = <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #66cc66;">&#40;</span>l.<span style="color: #006600;">length</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i=<span style="color: #CC0000;">0</span>; i&lt;l.<span style="color: #006600;">length</span>; i++<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    a<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> = String.<span style="color: #006600;">fromCharCode</span><span style="color: #66cc66;">&#40;</span>l<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span> &amp; 0xFF, l<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>&gt;&gt;&gt;<span style="color: #CC0000;">8</span> &amp; 0xFF,</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">                   l<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>&gt;&gt;&gt;<span style="color: #CC0000;">16</span> &amp; 0xFF, l<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>&gt;&gt;&gt;<span style="color: #CC0000;">24</span> &amp; 0xFF<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">return</span> a.<span style="color: #006600;">join</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #003366; font-weight: bold;">function</span> escCtrlCh<span style="color: #66cc66;">&#40;</span>str<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000066; font-weight: bold;">return</span> str.<span style="color: #006600;">replace</span><span style="color: #66cc66;">&#40;</span>/<span style="color: #66cc66;">&#91;</span>\<span style="color: #CC0000;">0</span>\t\n\v\f\r\xa0<span style="color: #3366CC;">'&quot;!]/g, function(c) {</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">    return '</span>!<span style="color: #3366CC;">' + c.charCodeAt(0) + '</span>!<span style="color: #3366CC;">';</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">  });</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">}</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">function unescCtrlCh(str) {</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">  return str.replace(/!<span style="color: #000099; font-weight: bold;">\d</span><span style="color: #000099; font-weight: bold;">\d</span>?<span style="color: #000099; font-weight: bold;">\d</span>?!/g, function(c) {</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">    return String.fromCharCode(c.slice(1,-1));</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">  });</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">}</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">input=window.location;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">key=prompt(&quot;Pick an encryption key (you must type this every time you load the bookmark)&quot;);</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">sitename=window.document.title;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">encrypted=TEAencrypt(input,key);</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">the_code=TEAencrypt.toSource() + TEAdecrypt.toSource() + strToLongs.toSource() +</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">  longsToStr.toSource()+ escCtrlCh.toSource() + unescCtrlCh.toSource();</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">the_code=the_code.replace(/<span style="color: #000099; font-weight: bold;">\"</span>/g,&quot;'</span><span style="color: #3366CC;">&quot;);</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #3366CC;">document.write(&quot;</span>Bookmark <span style="color: #000066; font-weight: bold;">this</span> link:&lt;br/&gt;<span style="color: #66cc66;">&#91;</span>&lt;a href=\<span style="color: #3366CC;">&quot;javascript:&quot;</span>+ the_code +</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #3366CC;">&quot;; key=prompt('What is your decryption key?'); decrypted=TEAdecrypt('&quot;</span>+</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  encrypted+<span style="color: #3366CC;">&quot;', key); window.location=decrypted;<span style="color: #000099; font-weight: bold;">\&quot;</span>&gt;&quot;</span>+sitename+<span style="color: #3366CC;">&quot;&lt;/a&gt;]&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></li></ol></pre>
<p>This was more of a pain in the ass to write than it looks, trust me.  The fact that no syntax highlighter (including the one above) can comprehend the code well enough to even highlight it should illustrate why.</p>
<p><strong>This Is Stupid.  What Kind Of Crazy Person Is This Paranoid?</strong></p>
<p>Me.  I love the new trend toward social sharing on the internet, but some of the privacy issues make my neckhair stand on end.  I love the convenience of things like del.icio.us and Google Browser Sync, but the fact that I'm storing stuff somewhere other than my own machine makes me nervous.  It's an adjustment I'm still making, and until I'm fully adjusted I need to create crap like this to help me relax.</p>
<p>This bookmarklet is for everyone out there in the same boat.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nomachetejuggling.com/2007/11/06/craziest-bookmarklet-ever/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Java Compiler Generating Secret Methods</title>
		<link>http://www.nomachetejuggling.com/2007/10/10/java-compiler-generating-secret-methods/</link>
		<comments>http://www.nomachetejuggling.com/2007/10/10/java-compiler-generating-secret-methods/#comments</comments>
		<pubDate>Thu, 11 Oct 2007 02:30:16 +0000</pubDate>
		<dc:creator>Rod</dc:creator>
		
		<category><![CDATA[Programming]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.nomachetejuggling.com/2007/10/10/java-compiler-generating-secret-methods/</guid>
		<description><![CDATA[I'm going to show you a little trick that will add two methods to any Java class, without actually defining them.  Furthermore, these methods will be given package visibility, accessible by any class in the same package. 
First and foremost, credit for showing me this interesting javac tidbit goes to Ted Neward.  Ted [...]]]></description>
			<content:encoded><![CDATA[<p>I'm going to show you a little trick that will add two methods to any Java class, without actually defining them.  Furthermore, these methods will be given package visibility, accessible by any class in the same package. </p>
<p>First and foremost, credit for showing me this interesting <code>javac</code> tidbit goes to <a href="http://blogs.tedneward.com/">Ted Neward</a>.  Ted recently presented an introduction to java bytecode at a local JUG.  The entire presentation was incredibly interesting, but one of the more interesting bits that came out was a little bit of trickery the java compiler performs in certain cases.</p>
<p>Let's take a look at two classes.   One we'll call CompTest, which will be a simple class that contains a private String and a method to print it to the screen.  The second will be CompExecutive, which will simply make a CompTest instance and call the one method it defines.  It will also use Java reflection to count the number of methods on CompTest.</p>
<pre class="java"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> CompTest <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000000; font-weight: bold;">private</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3AString+java.sun.com&amp;bntI=I%27m%20Feeling%20Lucky"><span style="color: #aaaadd; font-weight: bold;">String</span></a> myVariable=<span style="color: #ff0000;">&quot;This is a private variable&quot;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #993333;">void</span> printVar<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">    <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3ASystem+java.sun.com&amp;bntI=I%27m%20Feeling%20Lucky"><span style="color: #aaaadd; font-weight: bold;">System</span></a>.<span style="color: #006600;">out</span>.<span style="color: #006600;">println</span><span style="color: #66cc66;">&#40;</span>myVariable<span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">  <span style="color: #66cc66;">&#125;</span></div></li><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #66cc66;">&#125;</span></div></li></ol></pre>
<pre class="java"><ol><li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;"><div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #a1a100;">impor