1

I'm looking for an efficient way to build a random string that has specific requirements but can vary in length. It must:

  • Contain at least one uppercase character.
  • Contain at least one lowercase character.
  • Contain at least one number.
  • Contain at least one of the special characters: _-|@.,?/!~#$%^&*(){}[]+=

The random string doesn't have to be unique but if it is, its better. It will be used in a node.js server so any crypto library can be made use of. I saw Math.random().toString(36) which comes close but doesn't get me everything. I'm not sure if I should just try to build a regex for this.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Xerri
  • 4,916
  • 6
  • 45
  • 54

2 Answers2

3
var randomString = (function() {
  // Define character classes to pick from randomly.
  var uppers = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  var lowers = 'abcdefghijklmnopqrstuvwxyz';
  var numbers = '0123456789';
  var specials = '_-|@.,?/!~#$%^&*(){}[]+=';
  var charClasses = [uppers, lowers, numbers, specials];
  var minLen = charClasses.length;
  function chooseRandom(x) {
    var i = Math.floor(Math.random() * x.length);
    return (typeof(x)==='string') ? x.substr(i,1) : x[i];
  }
  // Define the function to actually generate a random string.
  return function(maxLen) {
    maxLen = (maxLen || 36);
    if (maxLen < minLen) { throw new Error('length must be >= ' + minLen); }
    do { // Append a random char from a random char class.
      var str='', usedClasses={}, charClass;
      while (str.length < maxLen) {
        charClass = chooseRandom(charClasses);
        usedClasses[charClass] = true;
        str += chooseRandom(charClass);
      }
      // Ensure we have picked from every char class.
    } while (Object.keys(usedClasses).length !== charClasses.length);
    return str;
  }
})();

randomString(); // => "o4m3H@YC7j0r@^gsY@1vlg2]cI66|9^beZ1)"
randomString(); // => "R6-K0Kq%4O0Je*=iPbVaV|bo-_,,g[j8wTW2"
randomString(); // => "!uu5NUWs1P}SRN78l}32Gno$]2m5PV+h+wTG"
maerics
  • 151,642
  • 46
  • 269
  • 291
0

Regex are used to check, capture, split or replace something in a string, you can't build something from zero with them.

However you can make some replacement in a string that contain a random generated number to have that you want.

Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
  • I thought of that but it will loose a level of uniqueness if I'm just replacing chars. ATM I'm trying Math.random() to build the string. – Xerri Jun 13 '13 at 14:03