Create a random token in Javascript based on user details
Asked Answered
B

6

38

I want to create a random string (token) which can be used to identify a user whilst avoiding any potential conflicts with any other users' tokens.

What I was thinking of was an MD5 hash of navigator.userAgent + new Date().getTime() to generate the token but that requires a whole Javascript MD5 library to hash it which I don't really want to do.

It has to be made up of A-Z/0-9 characters and ideally no longer than 32 characters. I am open to all ideas. Thanks!

Just to clarify I'm not looking for any random string generator, the random string has to be generated from the users details available through Javascript and can also use time to avoid potential conflicts!

Betts answered 16/12, 2011 at 9:50 Comment(1)
as you have written, the only thing that comes to my mind is a hash function. you might want to try to google something like "hash function javascript" and maybe you will find sometihng lightweightMond
W
146

You could generate a random number and convert it to base 36 (0-9a-z):

var rand = function() {
    return Math.random().toString(36).substr(2); // remove `0.`
};

var token = function() {
    return rand() + rand(); // to make it longer
};

token(); // "bnh5yzdirjinqaorq0ox1tf383nb3xr"
Wasteful answered 16/12, 2011 at 9:53 Comment(5)
@fire: I think this doesn't practically cause conflicts. MD5 theoratically can also cause conflicts, but you shouldn't need to worry about that.Wasteful
It could conflict, if the token was generated through someones own browser information + your method that would be better.Betts
@fire: I don't fully get your point. navigator.userAgent isn't unique for everyone, so it doesn't make it bulletproof.Wasteful
Removing radix (36) parameter from .toString in rand function will give you numeric-only hash -- if someone would like for the one like that: return Math.random().toString().substr(2);Quyenr
Man I love a sweet one-liner!Walkway
J
13

I use an approach similar to Kareem's, but with fewer function calls and built-in array operations for a big boost in performance.

According to a performance test, this method also outperforms the accepted answer by a small margin. Moreover it provides a parameter n to generate any size token length from a white list of acceptable characters. It's flexible and performs well.

function generateToken(n) {
    var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    var token = '';
    for(var i = 0; i < n; i++) {
        token += chars[Math.floor(Math.random() * chars.length)];
    }
    return token;
}
Judon answered 30/12, 2017 at 6:21 Comment(0)
J
12

This function allows you to set the token length and allowed characters.

function generate_token(length){
    //edit the token allowed characters
    var a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split("");
    var b = [];  
    for (var i=0; i<length; i++) {
        var j = (Math.random() * (a.length-1)).toFixed(0);
        b[i] = a[j];
    }
    return b.join("");
}

Simply call generate_token

generate_token(32); //returns "qweQj4giRJSdMNzB8g1XIa6t3YtRIHPH"
Jugurtha answered 22/10, 2017 at 13:3 Comment(1)
The other answer is smaller and faster, but I like the fact that this one lets you choose the length and the allowed characters.Eaton
P
11

//length: defines the length of characters to express in the string

const rand=()=>Math.random(0).toString(36).substr(2);
const token=(length)=>(rand()+rand()+rand()+rand()).substr(0,length);

console.log(token(40));
//example1:  token(10) => result: tsywlmdqu6
//example2:  token(40) => result: m4vni14mtln2547gy54ksclhcv0dj6tp9fhs1k10
Pluckless answered 13/6, 2018 at 13:8 Comment(0)
J
4

It is very unlikely, but Math.random() could return 0.0. In that case, the solution of pimvdb would return "" (empty string). So, here is another solution, which returns in every case a random base36 with 10 chars length:

function generateToken() {
    return Math.floor(1000000000000000 + Math.random() * 9000000000000000)
          .toString(36).substr(0, 10)
}
Jabez answered 7/5, 2018 at 9:6 Comment(0)
S
-1
let token = (Date.now()).toString(16); // '18f21c32dc5'.
Serviceberry answered 27/4 at 23:13 Comment(3)
Although this code might answer the question, I recommend that you also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes.Glisten
This does not answer the question at all. It's not random, not user-related...Magenmagena
What's unclear here? Could the current date happen again? And when is the date added to the image name? Is this also a non-random number? And the expression that was written above: returns rand() + rand().. How does it relate to the user?Adrianeadrianna

© 2022 - 2024 — McMap. All rights reserved.