jeudi 31 octobre 2019

How To Get A Unique Random Token Without Searching The Database

I came up with a function that seems to generate a different random token every time, and decided to share it incase it is useful. The token generator includes milliseconds since 1970 to improve randomness.

function randomTimeBasedToken(){
    function getTokenNumber(){
        let d = new Date();
        let millis1 = Math.floor(d.getTime()/1000);
        let wait = 1;
        while(Math.random() > 0.4 && wait < 25){wait++;}
        d = new Date();
        let millis2 = Math.floor(d.getTime()/1000);
        let millis = (millis1*millis2)+(wait*Math.floor(Math.random()*10000));
        millis = Number(millis.toString().split('').reverse().join(''));
        return millis+wait.toString()+Math.floor(Math.random()*10000);
    }
    let numString1 = getTokenNumber(); let numString2 = getTokenNumber();
    while(numString1.length < numString2.length){numString1 += '0';}
    while(numString2.length < numString1.length){numString2 += '0';}
    numString1 = numString1.split(''); numString2 = numString2.split('');
    for(let i = 0; i < numString1.length; i++){
        if(numString1[i] && numString2[i]){
            numString1[i] = (Number(numString1[i])+Number(numString2[i])).toString();
        }
    }
    numString1 = numString1.join(''); numString2 = numString2.join('');
    let tokenNumber = numString1.toString()+numString2.toString();
    let token = btoa(tokenNumber).split('=').join('');
    token = token.split('');
    let editDigit = 0;
    for(let i = 0; i < token.length; i++){
        if(i % 10 === 0){
            editDigit = 1;
            token[i] = Math.floor(Math.random()*1000);
        }else if(editDigit > 0 && editDigit <= 5){
            editDigit++;
            token[i] = '';
        }
    }
    token = token.join('');
    return token.toString();
}

I put together this little function to scan for duplicate tokens:

let tries = 10000;

let randTokens = []; let tokenMatches = 0;
for(let i = 0; i < tries; i++){
    let token = randomTimeBasedToken();
    if(randTokens.includes(token)){
        tokenMatches++;
    }
    randTokens.push(token);
}
console.log('');
console.log('Token Duplicates:', tokenMatches);
console.log('Tries: ', tries);

I've tested this with 100000 tries, and it returned 0 duplicates I would try 1 million, but so far it seems that will take my computer 30 minutes to an hour to process 1000000. Processing 1 doesn't take long, but looping the function 100000 times takes about a minute or 2.




Aucun commentaire:

Enregistrer un commentaire