Implementations

From Geohashing
Revision as of 12:30, 22 June 2008 by 92.48.114.82 (talk) (Automatic GPX File Generator)

If you're looking to code your own utilities, you will need a source that provides the Dow's opening price for any given day. Details on such services are available at Dow Jones Industrial Average.

6F4MhP <a href="http://jojecsnylmvp.com/">jojecsnylmvp</a>, [url=http://pxqfglovadqf.com/]pxqfglovadqf[/url], [link=http://mfdoaxgripoc.com/]mfdoaxgripoc[/link], http://snervepojheb.com/

I have seen all Internet... Anything... , http://oratiursal.nireblog.com/post/2008/06/22/alice-cooper-press-kit alice cooper press kit

038559,  http://ottymaky.wordpress.com/2008/06/22/alice-cooper-brutal-planet/ alice cooper brutal planet
rxpnb,  http://ulasanche.wordpress.com/2008/06/22/alice-cooper-frankenstien/ alice cooper frankenstien
muxej,  http://searfrodin.nireblog.com/post/2008/06/22/alice-cooper-tablature alice cooper tablature
zybah,  http://blogs.grab.com/cazharve/590621 desperado alice cooper
510124,  http://physhany.wordpress.com/2008/06/22/alice-com-com-cooper-google/ alice com com cooper google
037716,  http://ulasanche.wordpress.com/2008/06/22/alice-cooper-dvds/ alice cooper dvds
65593,  http://blogs.grab.com/cazharve/590632 hard rock summer alice cooper
:-(((,  http://ulasanche.wordpress.com/2008/06/22/alice-cooper-dvd-trade/ alice cooper dvd trade
cyvq,

The Friends, who heard what your opinion on the about the? , http://malduanbj.nireblog.com/post/2008/06/22/alice-cooper-im-eighteen-mp3 alice cooper im eighteen mp3

=)),  http://oratiursal.nireblog.com/post/2008/06/22/alice-cooper-restaurant-phoenix alice cooper restaurant phoenix
6880,  http://blogs.grab.com/fayvern/590645 rusty alice cooper royce
70093,  http://ottymaky.wordpress.com/2008/06/22/alice-cooper-clones-lyrics/ alice cooper clones lyrics
405,  http://ottymaky.wordpress.com/2008/06/22/alice-cooper-concert-history/ alice cooper concert history
:)),  http://ulasanche.wordpress.com/2008/06/22/alice-cooper-eighteen-tab/ alice cooper eighteen tab
712688,  http://oratiursal.nireblog.com/post/2008/06/22/alice-cooper-restaurant-cleveland alice cooper restaurant cleveland
>:OO,  http://searfrodin.nireblog.com/post/2008/06/22/alice-cooper-schools-out-for-summer alice cooper schools out for summer
5052,  http://ellwyla.nireblog.com/post/2008/06/22/adult-acute-myeloid-leukemia adult acute myeloid leukemia
mbixvq,

I sell the. Write on mine e-mail., http://glynnquabi.nireblog.com/post/2008/06/22/adult-animated-card-greeting adult animated card greeting

zkmctv,  http://glynnquabi.nireblog.com/post/2008/06/22/adult-animated-cartoons-free adult animated cartoons free
3929,  http://ulasanche.wordpress.com/2008/06/22/alice-cooper-im-eighteen/ alice cooper i'm eighteen
agzma,  http://ottymaky.wordpress.com/2008/06/22/alice-cooper-dead-baby/ alice cooper dead baby
8)),  http://physhany.wordpress.com/2008/06/22/alice-cooper-trash/ alice cooper - trash
gwnhgl,  http://blogs.grab.com/neylsanj/590676 adult asian live web cam
34567,  http://ulasanche.wordpress.com/2008/06/22/alice-cooper-i-love-the-dead-lyrics/ alice cooper i love the dead lyrics
804,  http://ellwyla.nireblog.com/post/2008/06/22/adult-add-com adult add com
>:],  http://blogs.grab.com/cazharve/590655 eighteen alice cooper lyrics
5247,

Order and buy the in ours online-shop! , http://blogs.grab.com/neylsanj/590708 adult ass dating rumprater.com

=-PP,  http://ottymaky.wordpress.com/2008/06/22/alice-cooper-detroit/ alice cooper detroit
43597,  http://quynwalt.nireblog.com/post/2008/06/22/adult-adventure-games adult adventure games
epncd,  http://blogs.grab.com/neylsanj/590694 adult asian film
rigsg,  http://blogs.grab.com/neylsanj/590687 adult asian free video
261,  http://glynnquabi.nireblog.com/post/2008/06/22/adult-animated-clip adult animated clip
omwuf,  http://glynnquabi.nireblog.com/post/2008/06/22/adult-animated-dirty-cartoons adult animated dirty cartoons
csob,  http://meegiverna.nireblog.com/post/2008/06/22/adult-american-bulldogs-for-sale adult american bulldogs for sale
06786,  http://ottymaky.wordpress.com/2008/06/22/alice-cooper-desperado-lyrics/ alice cooper desperado lyrics
2776,

And who sells? Give its phone number? The under the low prices! Call or write!, http://ellwyla.nireblog.com/post/2008/06/22/adult-add-online adult add online

%-]]],  http://meegiverna.nireblog.com/post/2008/06/22/adult-amidala-costume adult amidala costume
cbiimt,  http://blogs.grab.com/tadlwendel/590743 adult art bondage work
abuimg,  http://blogs.grab.com/tadlwendel/590755 adult arizona entertainment
%)),  http://blogs.grab.com/garlywartin/590730 adult babe bomis video
knn,  http://pinglen.nireblog.com/post/2008/06/22/adult-adultdvdonlinestorenet-college-dvd-movie-sex-video adult adultdvdonlinestore.net college dvd movie sex video
=]]],  http://tashylato.wordpress.com/2008/06/22/2-adult-sims-skin/ 2 adult sims skin
:-[,  http://glynnquabi.nireblog.com/post/2008/06/22/adult-animated-fantasy adult animated fantasy
=-[,  http://blogs.grab.com/garlywartin/590732 adult babe baby erotic lady most teen woman
>:OOO,

Would you like to see. Coquitlam provides both garbage and recycling collection for City residents, along with drop-off locations for larger disposal items and composting information., http://meegiverna.nireblog.com/post/2008/06/22/adult-among-suicide-teen-young adult among suicide teen young

8-],  http://tashylato.wordpress.com/2008/06/22/1st-adult-finder-friend-friendfindinginfo-in-matchmaking/ 1st adult finder friend friendfinding.info in matchmaking
8-OOO,  http://blogs.grab.com/neylsanj/590772 adult asian model
jxf,  http://quynwalt.nireblog.com/post/2008/06/22/adult-adventure-free-game-sex adult adventure free game sex
8O,  http://blogs.grab.com/tadlwendel/590789 adult arlington care facility
rwjvv,  http://blogs.grab.com/neylsanj/590762 adult asian clip movie
gbmm,  http://blogs.grab.com/neylsanj/590777 adult aspergers syndrome
32907,  http://blogs.grab.com/tadlwendel/590792 adult arizona hotel motel xxx
>:-((,  http://meegiverna.nireblog.com/post/2008/06/22/adult-among-cigarette-smoking adult among cigarette smoking
uayk,

Where it is possible to order the in us?, http://bisrahma.wordpress.com/2008/06/22/3d-adult-animated-comic/ 3d adult animated comic

373,  http://blogs.grab.com/tadlwendel/590829 adult arcade video game
%[[,  http://blogs.grab.com/gaenagerla/590828 adult audience figurine item mature
52282,  http://blogs.grab.com/tadlwendel/590832 adult archie comic
8-(((,  http://blogs.grab.com/garlywartin/590810 adult babies
807135,  http://blogs.grab.com/neylsanj/590842 adult asian web cam
ils,  http://blogs.grab.com/garlywartin/590802 adult baby and diaper lover stories
8-DD,  http://blogs.grab.com/tadlwendel/590825 adult arcade location video
0241,  http://blogs.grab.com/gaenagerla/590830 adult audience item mature toy
9389,

The City of Arlington's goal is 500 pledges. Thank you for doing your part., http://blogs.grab.com/marheyd/590885 similar site youtube

amyu,  http://quynwalt.nireblog.com/post/2008/06/22/adult-adultnewreleasecom-dvd-lesbian-movie-porn-star-video adult adultnewrelease.com dvd lesbian movie porn star video
cryoc,  http://quynwalt.nireblog.com/post/2008/06/22/adult-adultnewreleasecom-download-dvd-movie-movie-porn-sex-star adult adultnewrelease.com download dvd movie movie porn sex star
=[[[,  http://havilynd.wordpress.com/2008/06/22/80-adult-older/ 80 adult older
xgxtg,  http://blogs.grab.com/tadlwendel/590876 adult archive erotica jpeg pic posting
881,  http://blogs.grab.com/tadlwendel/590873 adult archive comic
910077,  http://urantail.nireblog.com/post/2008/06/22/adult-allegheny-county-probation adult allegheny county probation
68385,  http://manfalbu.wordpress.com/2008/06/22/adhd-adult-because-can-trauma-witnessing/ adhd adult because can trauma witnessing
>:(((,  http://tashylato.wordpress.com/2008/06/22/1af1934-adultresults2ejsp1f-jrun-search-search/ 1af1934 adultresults2ejsp1f jrun search search
=P,

I have an information on the the is well! , http://wakchio.nireblog.com/post/2008/06/22/adult-affiliate-marketing-programs adult affiliate marketing programs

9284,  http://blogs.grab.com/reyndarian/590913 adult author boyd david young
%[[,  http://ivortarco.nireblog.com/post/2008/06/22/adult-anime-free-porn adult anime free porn
jaofj,  http://wakchio.nireblog.com/post/2008/06/22/adult-affiliate-click-pay-per-program adult affiliate click pay per program
8D,  http://glynnquabi.nireblog.com/post/2008/06/22/adult-animated-graphic adult animated graphic
193559,  http://wakchio.nireblog.com/post/2008/06/22/adult-affiliate-book-guest-inurl-program-toy adult affiliate book guest inurl program toy
lthdg,  http://meegiverna.nireblog.com/post/2008/06/22/adult-amoxicillin-dose adult amoxicillin dose
29821,  http://evapeel.nireblog.com/post/2008/06/22/adult-adult-adultdvdonlinestorenet-movie-porn-sale-video adult adult adultdvdonlinestore.net movie porn sale video
wtpac,  http://blogs.grab.com/gaenagerla/590898 adult austin in outpatient treatment young
842331,

GeohashGenerator for Popfly

This implementation IS FULLY 30W-compliant.

I have created a Popfly block to use for creating mashups at http://www.popfly.com/users/rbuckton/GeohashGenerator. Can be integrated with Virtual Earth, etc.

rbuckton

Lazy Geohasher

This implementation IS PARTIALLY 30W-compliant.

If you'd rather just stay at home and wait for a geohash to come to you (or perhaps have some other reason to participate in Geohash Hacking), there's a perl script which will search for combinations of times and DOW Jones opening prices to find when you could win the much coveted Couch Potato Geohash or Cubicle Geohash award. Just put in the ranges of values for the stock market and the time you want to wait for, and watch those CPU cycles fly! -- thaniel.drake@gmail.com.

30w compliance statement: This code does not use live data. Users are expected to determine from the date of the Geohash which opening value is relevant for their locale.

Disclaimer: The author humbly requests that you do not manipulate the Dow Jones Industrial Average to ensure that a geohash collides with your address. The author accepts no responsibility for any resulting financial instability you cause by such manipulations.

Here is an improved implementation which sorts results by great-circle distance. Distance cutoff, length of search, and dollar spread searched may be adjusted at the command line. Days may be a positive integer count of days following today or a comma-separated list of %F datespecs. Same 30W caveats apply.

This implementation IS PARTIALLY 30W-compliant.
#!/usr/bin/perl -w
require 5.9.2;

use Digest::MD5 qw(md5);
use POSIX qw(strftime);
use Math::Trig qw(deg2rad great_circle_distance);

die "usage: $0 lat lon orig-dow [spread] [days] [max-km]" unless @ARGV >= 3;
my ($lat, $lon, $orig, $spread, $days, $max_km) = @ARGV;
my ($g_lat, $g_lon) = map { int } $lat, $lon;
$spread ||= 500; $days ||= 7; $max_km ||= 1;

sub geohash { map { $_ / 2**64 } unpack("Q>Q>", md5(shift)) }
sub genday {
    my $date = shift;
    for (($orig - $spread) * 100 .. ($orig + $spread) * 100) {
        my $dow = sprintf("%.2f", $_ / 100);
        ($f_lat, $f_lon) = map { substr($_, 1) } geohash("$date-$dow");
        $gh{"$date-$dow"} = [$g_lat . $f_lat, $g_lon . $f_lon];
    }
}

if ($days =~ /^\d{4,}-\d{2}-\d{2}/) { genday($_) for split(/,/, $days) }
else { genday(strftime("%F", localtime(time + 86400 * $_))) for (1...$days) }

sub d2r { deg2rad($_[0]), deg2rad(90 - $_[1]) }
sub gdist { great_circle_distance(d2r($lat, $lon), d2r(@{$_[0]}), 6378) }

printf "%s -> %f,%f (%.3fkm)\n", $_->[0], @{$gh{$_->[0]}}, $_->[1] for
    sort { $a->[1] <=> $b->[1] }
        grep { $_->[1] < $max_km }
            map { [$_, gdist($gh{$_})] } keys %gh;

For discussion of the actual algorithm stuff hiding in there, please see the next section.

Alternative Perl Implementiation

Because there is no way this page is complete without a lesson on endianness...

In writing the above "lazy" script I needed to come up with a way to do the actual hashing in Perl. So, here it is pulled out from that, and using today's data from the web service:

This implementation IS FULLY 30W-compliant.
#!/usr/bin/perl -w
require 5.9.2;

use POSIX qw(strftime);
use LWP::Simple;
use Digest::MD5 qw(md5);

die "usage: $0 lat long" unless @ARGV == 2;
my @graticule = map { int } @ARGV;

sub dow_open {
    my $date = strftime("%Y/%m/%d", localtime(shift));
    get("http://irc.peeron.com/xkcd/map/data/$date");
}

sub geohash {
    map { $_ / 2**64 } unpack("Q>Q>", md5(shift));
}

my $today = strftime("%F", localtime);
my $dow = dow_open(time - ($graticule[1] > -30 ? 86400 : 0));

for (map { substr($_, 1) } geohash("$today-$dow")) {
    print shift @graticule, $_, "\n";
}

This is the same bare output format as the shell script, for piping into your favorite formatter or google-launcher or whatever. The reason it requires Perl 5.10, however, is the code used to interpret the hash:

map { $_ / 2**64 } unpack("Q>Q>", md5(shift))

One unfortunate thing I have noticed across implementations is that a lot of effort has been spent converting hexadecimal into decimal. It is important to remember that MD5 hashes are 128 *bits* -- hexadecimal is just a form of representation. (It's very convenient, and we see it everywhere. But even in the original comic, it's representation.) In languages that provide the power to deal with data directly, the familiar hex representation can frequently be skipped in our quest to present numbers as decimal. This is what unpack does above (The Python implementation uses their flavor of unpack as well. I am sure Ruby has something similar).

I point this out only because Perl neglected to get this right until recently, and so the code as written will not run on 5.8 or earlier. As they are presented in the algorithm, the two 64-bit binary fractions (think: 1/2's place, 1/4's place, 1/8's place... with the caveat that we only see the numerator digits; the denominators are all 1!) from the 128 bits of MD5 are big-endian. Sadly, the machine running Perl might be big-endian or little-endian (think: the first 8 places at the end, then the next 8 places before that, etc... it's reversed by bytes, not bits). 5.10 provides the "<" and ">" endianness specifiers for all types, even 64-bit numbers. But on 5.8, attempting to directly grab the bits will always use the machine's native arrangement, and so only work if you're in big-endian-land. Most of us (running x86 CPUs) are not. Here is one (ugly) way to deal with it:

map { $_ / 2**64 } reverse unpack("QQ", reverse md5(shift));

Evaluation works backward from the right; by reversing the byte string (remember how it's backwards by bytes? the word that looks forward to us looks backward to them, too), we are able to unpack two 64-bit chunks that *would* be the right numbers, but are now (since the whole thing was reversed) in the wrong order, so we flip them around again. If they weren't the same sizes, we would have had to reverse the unpack specification as well (in fact, we did; you just couldn't tell). Fun, no? So if you need to run this on 5.8, patch this in and remember to delete the "require" line.

Ruby Geohasher

This implementation IS FULLY 30W-compliant.

ScottKuma did this as a first excursion into Ruby. Yes, it's long. Yes, it's kinda clunky. However, IT WORKS!

Any changes, suggestions, etc. are happily accepted!


#!/usr/bin/ruby
#geohasher.rb

#Written by ScottKuma

# Can be run without any command-line arguments (and gets the current geohash for the graticule specified in myLat and myLong, below),
# a single argument (the date in YYYY-MM-DD or YYYY/MM/DD format), 
# two arguments (the latitude & longitude "base" coordinates), 
# or three arguments (latitude & longitude "base" coordinates, followed by the date.

require 'net/http'
require 'date'
require 'digest'

myLat = "39"	# Change me to set the desired default graticule's latitude
myLong = "-84"	# Change me to set the desired default graticule's longitude

def hexFracToDecFrac(hexFracPart)
	#I wish I had a neat little algorithm to do this in one line - but this works!
	#NOTE:  do not feed the preceding "0." to this function....only the fractional part (the part after the decimal point)
	fracLen = hexFracPart.length
	fracPortion = hexFracPart[0..(fracLen-1)]
	fracLen = fracPortion.length
	myLen = (fracLen - 1)
	sum = 0	
	for i in (0 .. myLen)
		numSixteenths = fracPortion[i..i].to_i(16)
		conversionFactor = (16.**(i+1)).to_f
		conversionFactor = 1./conversionFactor
		sum = sum + ((numSixteenths) * conversionFactor)
	end
	sum = sum.to_s
	return sum[2..8]
end

t=Time.now
myDate = t.strftime("%Y-%m-%d")

if ARGV.length == 1
	myDate = ARGV[0]
end

if ARGV.length == 2
	myLat = ARGV[0]
	myLong = ARGV[1]
end
	
if ARGV.length == 3
	myLong = ARGV[1]
	myLat = ARGV[0]
	myDate = ARGV[2]
end

dateSplit = ''
if myDate.split('/').length == 3
	dateSplit = myDate.split('/')
else
	dateSplit = myDate.split('-')
end

myDate = Date.civil(dateSplit[0].to_i, dateSplit[1].to_i, dateSplit[2].to_i)

#fix for the "-30 rule"
fixDate = Date.civil(2008,05,25)
timeDelta = 0
if myLong.to_i > -30 and (myDate > fixDate)
	puts "-30 rule in effect!"
	timeDelta = 1
end

algorithmEncodedDate = myDate.to_s
urlEncodedDate = (myDate - timeDelta).strftime('%Y/%m/%d')

baseURL = 'irc.peeron.com'
basePath = '/xkcd/map/data/'
fullPath = basePath + urlEncodedDate
dow = ""

Net::HTTP.start(baseURL,80) do |http|
	dow = http.get(fullPath).body
end

if !dow.include? "404 Not Found"
	ghash = algorithmEncodedDate+'-'+dow
	digest = Digest::MD5.hexdigest(ghash)
	digest1 = digest[0..15]
	digest2 = digest[16..31]
	puts "(" + myLat + "." + hexFracToDecFrac(digest1) + ", " + myLong + "." + hexFracToDecFrac(digest2) + ")"
else 
	puts "Dow information not available for "+urlEncodedDate
end


Here's one way you could do hex to dec fraction in one line - it's "little", I'm not so sure about "neat"

def hexFracToDecFrac hexFracPart
  hexFracPart.split('').inject((cf=1)-1){|sum,c|sum+ c.to_i(16)/(cf<<=4).to_f}.to_s[2..8]
end

macHasher

This implementation IS FULLY 30W-compliant.
macHasher screenshot

Scottkuma worked feverishly to:

  1. learn Apple OSX Programming and...
  2. put together a geohash calculator for the Mac.

Installation:

It's a normal mac application - drag it to your Applications folder, OR just run it from inside the DMG. I think I compiled it as a Universal Binary. If you can't run it on a particular system and/or version of OSX, please let me know.

Usage:

Start by entering your graticule's Lat/Long numbers. The given numbers are for Cincinnati, Ohio.

For today's graticule, just click "Generate!" For dates in the past (or the near-future, for Saturday & Sunday graticules), select the date on the calendar, then click "Generate!"

Known bugs:

  • Requires a valid network connection; locks pretty good when one doesn't exist.
  • does not calculate east of -30 correctly for dates prior to 5/27/2008
  • window doesn't lock its size like I thought it would...

Planned enhancements:

  • will allow for saving of a known "home" location
  • will calculate distance & bearing to a known location
  • will calculate same for adjacent graticules to find a closer geohash