Google URL Shortener APIを利用する
goo.gl(6文字)。bit.ly(6文字)と同じというのが、対抗意識ばりばりというか、じゃあGoogleの強みとして述べているセキュリティとか速さをどれくらい体験出来るのかな、ということになる。
goo.gl短縮URLを作るための、APIは公開されていないのだが、Google Toolbarのxpiファイルをunzipし、lib/toolbar.js というファイルを読むと getUrlShorteningRequestParams_ という関数が見付かる。これが、Google URL Shortenerに投げるPOSTデータを生成している。
JavaScriptコードをPythonに変換してみた。関数名などは出来るだけそのままにしたが、一部は異なる記述を使っているので、JSコードを参照されたし。
#!/usr/bin/python # import struct import urllib import simplejson def _c(vals): l = 0 for val in vals: l += val & 4294967295 return l def _d(l): if l <= 0: l += 4294967296 m = str(l) o = 0 n = False for char in m[::-1]: q = int(char) if n: q *= 2 o += q / 10 + q % 10 # JSだと Math.floor(q / 10) + q % 10 else: o += q n = not(n) m = o % 10 o = 0 if m != 0: o = 10 - m if len(str(l)) % 2 == 1: if o % 2 == 1: o += 9 o /= 2 return str(o) + str(l) def _e(uri): m = 5381 for char in uri: # m = _c([m << 5, m, struct.unpack("B", char)[0]]) m = _c([m << 5, m, ord(char)]) return m def _f(uri): m = 0 for char in uri: # m = _c([struct.unpack("B", char)[0], m << 6, m << 16, -1 * m]) m = _c([ord(char), m << 6, m << 16, -1 * m]) return m def _make_auth_token(uri): i = _e(uri) i = i >> 2 & 1073741823 i = i >> 4 & 67108800 | i & 63 i = i >> 4 & 4193280 | i & 1023 i = i >> 4 & 245760 | i & 16383 h = _f(uri) k = (i >> 2 & 15) << 4 | h & 15 k |= (i >> 6 & 15) << 12 | (h >> 8 & 15) << 8 k |= (i >> 10 & 15) << 20 | (h >> 16 & 15) << 16 k |= (i >> 14 & 15) << 28 | (h >> 24 & 15) << 24 j = "7" + _d(k) return j def get_short_url(uri, user): if user is None: user = '[email protected]' token = _make_auth_token(uri) opt = 'user='+user+'&'+urllib.urlencode({'url':uri})+'&auth_token='+token # print opt ggl_url = 'http://goo.gl/api/url' res = urllib.urlopen(ggl_url, opt) # print res.read() short_url = simplejson.loads(res.read())['short_url'] return short_url if __name__ == "__main__": print get_short_url("http://www.aida.t.u-tokyo.ac.jp/", None)
$ python googl.py http://goo.gl/2YzP
Google Toolbarのアップデートに伴って使えなくなるかもしれないが、それまでエンジョイ。
- -
2009/12/17追記:
JavaScriptの charCodeAt() はUnicodeを扱えるから、struct.unpack("B",char)は不適切。ていうか、ord() で良かった。