following these steps below:
- install package
racket-base32:
raco pkg install https://github.com/sackpost/racket-base32.git- test it:
raco test google-auth.rkt
| #lang racket/base | |
| (require base32 | |
| file/sha1 | |
| web-server/stuffers/hmac-sha1 | |
| racket/contract) | |
| (define/contract (get-code key) | |
| (-> bytes? integer?) | |
| (let* ([key (base32-decode key)] | |
| [code (hex-string->bytes | |
| (string-append "0" | |
| (number->string (round (/ (current-seconds) 30)) 16)))] | |
| [fdb (bytes-append | |
| (apply bytes-append | |
| (for/list ([_ (- 8 (bytes-length code))]) | |
| (bytes 0))) | |
| code)] | |
| [hmac (HMAC-SHA1 key fdb)] | |
| [o (bitwise-and (bytes-ref hmac 19) 15)] | |
| [h (subbytes hmac o (+ o 4))] | |
| [q1 (arithmetic-shift | |
| (+ (arithmetic-shift (bytes-ref h 0) 8) | |
| (bytes-ref h 1)) | |
| 16)] | |
| [q2 (+ (arithmetic-shift (bytes-ref h 2) 8) | |
| (bytes-ref h 3))] | |
| [qq (+ q1 q2)] | |
| [mid (bitwise-and qq #x7fffffff)]) | |
| (remainder mid 1000000))) | |
| (module+ test | |
| (displayln (get-code #"VBKVUBKHV4EB2IEB"))) |