sophuwu.site > otpp   
              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;
    }
};