Generate random string/characters in JavaScript

2018-12-31 02:19发布

I want a 5 character string composed of characters picked randomly from the set [a-zA-Z0-9].

What's the best way to do this with JavaScript?

30条回答
泛滥B
2楼-- · 2018-12-31 03:05

Math.random is bad for this kind of thing

Option 1

If you're able to do this server-side, just use the crypto module

var crypto = require("crypto");
var id = crypto.randomBytes(20).toString('hex');

// "bb5dc8842ca31d4603d6aa11448d1654"

The resulting string will be twice as long as the random bytes you generate; each byte encoded to hex is 2 characters. 20 bytes will be 40 characters of hex.


Option 2

If you have to do this client-side, perhaps try the uuid module

var uuid = require("uuid");
var id = uuid.v4();

// "110ec58a-a0f2-4ac4-8393-c866d813b8d1"

Option 3

If you have to do this client-side and you don't have to support old browsers, you can do it without dependencies

// dec2hex :: Integer -> String
function dec2hex (dec) {
  return ('0' + dec.toString(16)).substr(-2)
}

// generateId :: Integer -> String
function generateId (len) {
  var arr = new Uint8Array((len || 40) / 2)
  window.crypto.getRandomValues(arr)
  return Array.from(arr, dec2hex).join('')
}

console.log(generateId())
// "82defcf324571e70b0521d79cce2bf3fffccd69"

console.log(generateId(20))
// "c1a050a4cd1556948d41"

查看更多
情到深处是孤独
3楼-- · 2018-12-31 03:05

A newer version with es6 spread operator:

[...Array(30)].map(() => Math.random().toString(36)[3]).join('')

  • The 30 is arbitrary number, you can pick any token length you want
  • The 36 is the maximum radix number you can pass to numeric.toString(), which means all numbers and a-z lowercase letters
  • The 3 is used to pick the 3rd number from the random string which looks like this: "0.mfbiohx64i", we could take any index after 0.
查看更多
刘海飞了
4楼-- · 2018-12-31 03:06
function randomString (strLength, charSet) {
    var result = [];

    strLength = strLength || 5;
    charSet = charSet || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

    while (--strLength) {
        result.push(charSet.charAt(Math.floor(Math.random() * charSet.length)));
    }

    return result.join('');
}

This is as clean as it will get. It is fast too, http://jsperf.com/ay-random-string.

查看更多
低头抚发
5楼-- · 2018-12-31 03:06

This works for sure

<script language="javascript" type="text/javascript">
function randomString() {
 var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
 var string_length = 8;
 var randomstring = '';
 for (var i=0; i<string_length; i++) {
  var rnum = Math.floor(Math.random() * chars.length);
  randomstring += chars.substring(rnum,rnum+1);
 }
 document.randform.randomfield.value = randomstring;
}
</script>
查看更多
只若初见
6楼-- · 2018-12-31 03:09

Here is a test script for the #1 answer (thank you @csharptest.net)

the script runs makeid() 1 million times and as you can see 5 isnt a very unique. running it with a char length of 10 is quite reliable. I've ran it about 50 times and haven't seen a duplicate yet :-)

note: node stack size limit exceeds around 4 million so you cant run this 5 million times it wont ever finish.

function makeid()
{
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

ids ={}
count = 0
for (var i = 0; i < 1000000; i++) {
    tempId = makeid();
    if (typeof ids[tempId] !== 'undefined') {
        ids[tempId]++;
        if (ids[tempId] === 2) {
            count ++;
        }
        count++;
    }else{
        ids[tempId] = 1;
    }
}
console.log("there are "+count+ ' duplicate ids');
查看更多
还给你的自由
7楼-- · 2018-12-31 03:11

Fast and improved algorithm. Does not guarantee uniform (see comments).

function getRandomId(length) {
    if (!length) {
        return '';
    }

    const possible =
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    let array;

    if ('Uint8Array' in self && 'crypto' in self && length <= 65536) {
        array = new Uint8Array(length);
        self.crypto.getRandomValues(array);
    } else {
        array = new Array(length);

        for (let i = 0; i < length; i++) {
            array[i] = Math.floor(Math.random() * 62);
        }
    }

    for (let i = 0; i < length; i++) {
        result += possible.charAt(array[i] % 62);
    }

    return result;
}
查看更多
登录 后发表回答