Code
def get_token(secret, digits=8, seconds=30)
t = Time.new.to_i
m = [t/seconds].pack("Q<").reverse
r = OpenSSL::HMAC.digest("sha1", [secret].pack("H*"), m)
k = r[19].ord
i = k & 0x0f
h = r[i...(i+4)].reverse.unpack("L<")[0] & 0x7fffffff
return (h % (10 ** digits)).to_s.rjust(8, "0")
end
Ruby version above ^^ note that all should be big endian but ruby supports it (or: different than native) in version 1.9.3+, and I want to run it on my cellphone where I only have 1.9.1 and cba to compile myself. So made it little endian + #reverse. On big endian systems you'd probably have to run with ruby 1.9.3+ OR remove those #reverse 's OR run on 1.9.3, remove reverses and change Q< to Q> and L< to L>
Secret + serial key has to be requested from blizz servers (kinda complicated scheme, but can post later when I'm done). Then just get_token("asdfasdfasdf") and we'll have currently working 8 digits for authenticator.
edit: and that's basically the part you'd have to do in pure C. Simple, eh? Except try to cut dependencies (e.g. implement hmac-sha1 yourself, not use openssl) to make it 100% portable. I wouldn't make requesting serial/secret in the same app.
This post was edited by ikusus on Jun 7 2012 03:59am