Recently I found this awesome 2-factor authentication code generator written in Python 3. I was trying to convert it to Swift 3, but I am having trouble with one specific part, though:
def get_hotp_token(secret, intervals_no):
key = base64.b32decode(secret)
msg = struct.pack(">Q", intervals_no)
h = hmac.new(key, msg, hashlib.sha1).digest()
o = h[19] & 15
h = (struct.unpack(">I", h[o:o+4])[0] & 0x7fffffff) % 1000000
return h
I so far have only been able to do the first line of the function body :p using code from here
func getHotpToken(secret: String) -> [Int] {
let data = secret.base32DecodedData
<...>
return theTokens
}
I tried reading the documentation on struct.pack here and reading about what packing actually is here, but I still find the concept/implementation confusing, and I have no idea what the equivalent would be in Swift.
According to the documentation, struct.pack returns a string in the given format. The format in my case is >Q, which means that the byte order is little-endian and the C Type is an unsigned long long. Again, I am not exactly sure how this is supposed to look in Swift.
... And that is only the second line! I don't really understand how HMAC works (I can't even find the actual 'background' code), so I can't even translate the entire function. I could not find any native library for Swift that has this behavior.
Any pointers or help translating this function will be highly appreciated!
P.S. I checked and I think that this is on topic
Relevant imports:
import base64, struct, hmac