58
#include <fstream>
#include <chrono>
#include <cstring>
#include <functional>
const static char base16[] = "0123456789ABCDEF";
struct OTP {
unsigned char bytes[16];
char* exportSecret() {
static char s[33];
for (int i = 0; i < 16; i++) {
s[i*2] = base16[(bytes[i] >> 4) & 15];
s[i*2+1] = base16[bytes[i] & 15];
}
s[32] = '\0';
return s;
}
void importSecret(char* s){
for(int i = 0; i < 16; i++) {
bytes[i] = ((strchr(base16, s[i*2]) - base16) << 4)
| (strchr(base16, s[i*2+1]) - base16);
}
}
void generateNewSecret() {
std::srand(std::chrono::high_resolution_clock::now().time_since_epoch().count());
int r, i, j;
for (i = 0; i < 16; i += 4) {
r = std::rand();
for (j = 0; j < 4; j++) {
bytes[i + j] = r & 255;
r >>= 8;
}
}
}
int currentToken(int validDuration = 30) {
int trunc = time(nullptr);
trunc = trunc - (trunc % validDuration);
unsigned char b[20];
int i = 0;
for (; i < 16; i++) b[i] = bytes[i];
for (; i < 20; i++) {
b[i] = trunc & 255;
trunc >>= 8;
}
unsigned long hash = std::hash<std::string>{}(std::string((char*)b, 20));
int token = 0;
for (;token < 100000;) {
token = hash % 1000000;
hash >>= 20;
}
return token;
}
};