Blog

Mayank Lahiri’s fabulous Foursquare gaming code challenge is an excellent write-up on a “small” problem with Foursquare’s check-in API.  You can check in from anywhere, but the system doesn’t verify where you are.  Clever programmers can get around this by taking notes of where their favorite venues are, and can then check-in whenever they want.  It may well be a long time before Foursquare learns to tell the difference between automated check-ins and people forgetting their keys.

The “challenge” in “coding challenge” is this: how short can we make a program that checks into Foursquare like a person would?  There are a couple of basic mechanisms in play.  First, you have to open a connection, log in, and then make a check-in.  As it turns out, Foursquare’s API lets us automate most of the work, so long as we’re willing to pretend to be a browser.  My entry into the challenge is not so much an original entry as it is a refinement of the challenge’s script, as such, the basic idea (a script written in Perl that pretends to be an iPhone) is the same.

I submitted three lines to the challenge, but as an exclusive for this blog, I have it down to two, each of which is reproduced below:

BEGIN {
    eval "use $_" for qw(MIME::Base64 IO::Socket)
}
readline do {
    printf({
        $sock = IO::Socket::INET->new(PeerAddr => 'api.foursquare.com',
                     PeerPort => 80, Proto => 'tcp', Type => SOCK_STREAM)
    } join (v13.10,
        "POST /v1/checkin HTTP/1.1" "Host: api.foursquare.com",
        "User-Agent: Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) "
            . "AppleWebKit/420+ (KHTML, like Gecko) "
            . "Version/3.0 Mobile/1C10 Safari/419.3",
        "Content-Type: application/x-www-form-urlencoded",
        "Authorization: Basic ${\encode_base64 'YOUR_USERNAME_HERE' . ':'
            . 'YOUR_PASSWORD_HERE'}", 'Content-Length: %2$s', '', '%1$s'
        ), local $_ = sprintf('vid=%s&private=0&geolat=%s&geolong=%s',
            $ARGV[0], map { $_ + rand() * 1e-4 - 5e-5 } @ARGV[1, 2]),
        2 + length),
    $sock
} if sleep rand() * 600

Almost all of the script’s code occurs in the call to printf().  The first argument in the curly braces is the filehandle to print to, and the rest are a series of strings concatenated by v13.10 (“\r\n”, of course).  I’m abusing $_ in order to save creating a $str variable (the format ‘%2$s %1$s’ will reverse the arguments to sprintf).  For maximum compatibility, I’ve used %s as a format for @ARGV[1, 2] despite them being floating-point.

As a signing-off note, astute readers will see that I submitted the vstring v15.12, which is incorrect.  I apologize for getting octal and decimal confused and hope that seasoned PDP-11 programmers can forgive me.

Related Posts:

  • No Related Posts
Post comment as twitter logo facebook logo
Sort: Newest | Oldest