Wednesday, August 10, 2011

Simple Search

I often come across interesting ideas and tools that I have no current use for but seem like they may be useful someday, so I bookmark them and hope I will recall them when needed. That process is what led to the current implementation of site search located at the bottom of each page on this blog.

At some point I came across an article on the the Google Webmaster Central Blog about enhancing a site's 404 page. I thought it was a pretty cool idea, and I'm using it on this site. The required code is very short:

 <script type="text/javascript">
	var GOOG_FIXURL_LANG = 'en';
	var GOOG_FIXURL_SITE = 'http://www.example.com'
 </script>
 <script type="text/javascript"
	src="http://linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js">
 </script>

The most interesting thing about it is that it adds a search form. It doesn't actually submit a form. It simply changes the current page's location to "http://www.google.com/search?q=site:www.heathanderson.net" (with the text from the text box appended) using JavaScript. This limits the Google search to (in this case) pages from my site. It is a really simple concept that I would like to think I would of eventually thought of (but probably wouldn't have).

When I needed a search for this site I decided to try this technique. So here it is, a simple search script:

 <script type="text/javascript">
	function simpleSearch(form) {
		var q = window.encodeURIComponent(form["q"].value);
		var url = "http://www.google.com/search?q=site:www.heathanderson.net ";
		url = url + q;window.location = url;
		return false;
	}

 </script>
 
 <noscript>
  You can search this site using <a href="http://www.google.com/search?q=site:www.heathanderson.net">Google</a>.
 </noscript>
 
 <form onsubmit="return simpleSearch(this)" method="get" id="searchForm">
    <input type="text" size="40" name="q" placeholder="Search this site...">
    <input type="submit" value="Search">
 </form>

I could have created the form element in JavaScript and appended it to the page, but that seemed more complicated than necessary. I also could have used an event handler instead of the inline onsubmit attribute, but again I point to the complexity. This way avoids most cross-browser pitfalls, and has the advantage of simplicity. I also added a link to Google inside a noscript tag for people that have JavaScript disabled.

Friday, August 05, 2011

Another Blog Redesign

HTML5 bannerI've decided to change the design of the this blog once again. I've radically simplified the site. The side bar is gone. The comment section is gone. Pretty much all the JavaScript is gone (the exception being the search box at the bottom of each page). The site is now HTML5--no more XHTML.

I am still using Jekyll to generate the HTML files of the site. I love the simplicity of it. I'm hosting the site on Amazon S3. It is fast, cheap and maintenance free.

I hope this new, streamlined version of my site will encourage me to post more. I guess we'll see.

Tuesday, September 07, 2010

Programming Fonts

I recently read a thread on Hacker News that got me thinking about the font I use when programming. I spend about eight hours a day looking at text in Textmate, but I've never really thought about the font. I didn't even know what font I was using. So I decided to do some research.

Apparently I was using Monaco 12pt.

monaco example

As you can see it is a little largish, but it never really bothered me. I began to search for other fonts to try. The first resource I found was Jeff Atwood's Programming Fonts post. I saw nothing that made me want to switch even temporarily. Next I looked at Top 10 Programming Fonts. I decided I might as well try out a couple of these fonts, even if just for a few minutes. I downloaded Monofur, Inconsolata, and Envy Code R. Envy Code R wasn't mentioned in the list, but it was brought up in the comments and in the Hacker News thread above.

There seems to be no 'best' font. Font preference seems to vary immensely from person to person. I had a hard time deciding if I actually have a preference. After a couple of days of font switching I finally decided on Inconsolata 12pt. I really don't know why. That makes it impossible for me to actually suggest a font to someone else, but I do recommend trying out some different fonts and seeing if one of them makes your time staring at text a little more pleasant.

Here is what my screen looks like now:

inconsolata example

One final note on anti aliasing: It seems that I like it (at least with Inconsolata and Monaco), some people do not. As with font choice I suggest trying it out and seeing for yourself.

Monday, September 06, 2010

Welcome to the new blog

I've finally had time to move my personal blog off of Wordpress.com. Now it is just static HTML generated by Jekyll. The new address is http://www.heathanderson.net; http://www.blogofheath.com will redirect there.

I hope to posting *something* at least once a month. I know that doesn't sound like a lot, but I've had a blog for about a year and only have four previous posts. That is kind of pathetic. I'm planning on posting more than just code related stuff, so-- if programming doesn't interest you --maybe all hope of you reading future posts isn't lost.

What am I using to generate this site? Here is the list:

I'm hosting this on Linode. Server side is the usual--Apache. I'm deploying using git's post receive hook. It is pretty sweet.

Monday, November 23, 2009

Ruby on Rails Plugin: string_encryption

This is a very simple Ruby on Rails plugin that allows easy encryption of strings. For the sake of simplicity there no customization. The only cipher used is 'des-ede3-cbc' (Triple DES using Cipher Block Chaining) . See my post on encrypting/decrypting a string with Ruby for more information. First install the plugin:

Next we need to add an encryption key as the constant @ENV['STRING_ENCRYPTION_KEY']@. To do this just run

  script/generate encryption_key

or you could set

  ENV['STRING_ENCRYPTION_KEY'] = "somekey"

where "somekey" is your key in environment.rb.

Now encryption/decryption is easy.

Encryption:

  "Test".encrypt  #=> "NDFkZTc5NDEyNTg1MzdiZPzBrxZz5aoN%0A"

Decryption:

  "NDFkZTc5NDEyNTg1MzdiZPzBrxZz5aoN%0A".decrypt  #=> "Test"

Code at Github:
http://github.com/handerson/string_encryption

Sunday, September 27, 2009

Initialization Vector Length in MRI Ruby versus JRuby

When using OpenSSL encryption in standard Ruby, the length of an initialization vector (IV) can apparently be as large as you want it to be as long as it is at least the minimum size. This is odd. This can also cause trouble when switching over to JRuby. JRuby appear to be much pickier about IV length.

This works in MRI but not in JRuby:

  unencrypted_data = "test"

  des = OpenSSL::Cipher::Cipher.new("des-ede3-cbc")
  des.encrypt
  des.key = '0123456789abcdef01234567890'

  des.iv = "ed87acdcca419954edccb736f7dc77a74f5ac8dfe3861c3d5f77248e21592131a5423d63ff91f07956ce1aa386f8359931b5" # 100 characters
  encrypted_data = des.update(unencrypted_data) + des.final

  puts encrypted_data

JRuby gives you this very helpful message:
@ruby_string_encryption.rb:27:in `encrypt': No message available (OpenSSL::Cipher::CipherError)
from ruby_string_encryption.rb:37@

Change the IV to 8 characters and everything works fine.

Update 10/14/2009 The code that I originally posted was incorrect. I have updated it. Also I opened a ticket for this issue.

If you are looking for what size an initialization vector should be check out my post on encrypting a string with Ruby.

Friday, September 25, 2009

Ruby String Encryption

Encrypting a string is fairly easy in Ruby. All you need to do is @require 'openssl'@. For this example I am using the 'des-ede3-cbc' (Triple DES using Cipher Block Chaining) cipher. Most--if not all--of the ciphers listed on OpenSSL.org as supported ciphers should work as well.

Triple DES requires a 24-byte key, with Ruby this means a string with 24 characters. We are also required to provide an initialization vector (IV). The IV is usually the same size as the block size of the cipher you are using (so says Wikipedia, so say we all). In our case this means an IV of 64-bits, or 8-bytes, or an 8 character Ruby String. If we randomize our IV and include it with our encrypted string then we can ensure that our encrypted data never looks the same even when we encrypt the same string multiple times.

  require 'openssl'

  KEY = '0123456789abcdef01234567890' # 24 characters

  string = "encrypt this"

  des = OpenSSL::Cipher::Cipher.new("des-ede3-cbc")
  des.encrypt # this tells OpenSSL what mode to operate in, here we want to encrypt data
  des.iv = iv = '01234567' # 8 characters, hard-coded for now

  data = des.update(string) + des.final  
  data = iv + data # this way when we randomize our IV it will be available when we need to decrypt the data

  puts data

This should output some crazy string. This isn't the friendliest way to send data, so lets do something about that. The easiest thing to do is Base 64 encode the data, and maybe URI escape it for good measure.

  # be sure to put the following at the top of your code:
  # require "base64"
  # require 'uri'
  # after 'the puts data' in the snippet above do the following:

  data = Base64.encode64(data)
  data = URI.escape(data, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))

  puts data

This should give you the much nicer @MDEyMzQ1Njd6jzSlS73fKSAdqYgRiJie%0A@.

Decryption is similarly easy.

  des = OpenSSL::Cipher::Cipher.new("des-ede3-cbc")
  des.decrypt
  des.key = KEY
  encrypted_data = URI.unescape(data)
  encrypted_data = Base64.decode64(data)
  des.iv =  encrypted_data.slice!(0,8) #This gives us our iv back and removes it from the encrypted data
  
  decrypted = des.update(encrypted_data) + des.final  
    
  puts decrypted

If you are using Rails or have access to ActiveSupport ActiveSupport::SecureRandom is a great way to generate your key and IV. Also be sure to check out ActiveSupport::MessageEncryptor and my string_encryption plugin. I'll probably do a writeup on the string_encryption plugin sometime next week.

Tuesday, September 22, 2009

Ruby on Rails Plugin: data_migration

data_migration allows you to separate data you need to load from your normal database migrations in a minimal way. While developing the new version of our flagship site, Knetwit, we decided we needed to separate our data migrations (initial settings and the like) from our structural migrations. We decided the easiest way to do this was to modify the existing Rails migration to allow for a new data migration. So we did.

Install Plugin

 
  script/plugin install git://github.com/handerson/data_migration.git

Generate Migration

 
  script/generate data_migration BlockedDomains 
  exists  db/data
  create  db/data/20090915161242_settings.rb[/sourcecode]

db/data/20090915161242_settings.rb:

 
  class BlockedDomains &lt; ActiveRecord::Migration
    def self.up
    end
  end

Add your data:

 
  def self.up
    BlockedEmailDomain.create(:domain => "mailinator.com")
    BlockedEmailDomain.create(:domain => "spamherelots.com")
    BlockedEmailDomain.create(:domain => "disposeamail.com")
  end

Run Migration

  rake db:data:migrate
 
  ==  BlockedDomains: migrating ===========================================================
  ==  BlockedDomains: migrated (0.0020s) ==================================================

db:data:migrate adds the data migration version number to the 'schema_migrations' table so it will not be ran again.

Code at Github:
http://github.com/handerson/data_migration