#include #include #include #include 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((char*)b, 20)); int token = 0; for (;token < 100000;) { token = hash % 1000000; hash >>= 20; } return token; } };