0

How to generate random numbers with below criteria in Javascript

  1. String should contain at least 4 lower case letters from [a-z]
  2. String should contain at least 4 upper case letters from [A-Z]
  3. String should contain at least 4 numbers from [0-9]

Note: I don't want to use any JS library due to leagacy reasons

I tried below code but it doesn't match above criteria for example sometimes it does not contain numbers at all....

function randomString(length, chars) {
    var mask = '';
    if (chars.indexOf('a') > -1) mask += 'abcdefghijklmnopqrstuvwxyz';
    if (chars.indexOf('A') > -1) mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    if (chars.indexOf('#') > -1) mask += '0123456789';
    var result = '';
    for (var i = length; i > 0; --i) result += mask[Math.round(Math.random() * (mask.length - 1))];
    return result;
}
document.write(randomString(12, 'aA#'));

Is there any better approach to do it?

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
Freephone Panwal
  • 1,547
  • 4
  • 21
  • 39

3 Answers3

2

Here's how you can do it: generate an array which represents your criteria, shuffle it and fill the array.

Example:

function makeRandomString(criteria) {

  // From http://stackoverflow.com/q/2450954/3371119
  function shuffle(array) {
      var currentIndex = array.length,
        temporaryValue, randomIndex;

      // While there remain elements to shuffle...
      while (0 !== currentIndex) {

        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;

        // And swap it with the current element.
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
      }

      return array;
  }
  // Choose a random character from a string
  function chooseRandom(str) {
      return str[Math.floor(Math.random() * str.length)];
  }
  // Shuffle the criteria
  shuffle(criteria);
  var result = "";
  // Build the resulting string by choosing a random character from each part
  for (var i = 0; i < criteria.length; ++i) result += chooseRandom(criteria[i]);
  return result;
}

Example usage:

// Some constants explaining the criteria
var lowercase = "abcdefghijklmnopqrstuvwxyz";
var uppercase = lowercase.toUpperCase();
var numbers = "0123456789";
// Note: if you don't like typing all that, change the names to L, N, and U
var criteria = [lowercase, lowercase, lowercase, lowercase, // 4 lowercase
                numbers, numbers, numbers, numbers, // 4 numbers
                uppercase, uppercase, uppercase, uppercase // 4 uppercase
               ];
console.log(makeRandomString(criteria));

Or even better (much less typing):

function repeat(elem, n) {
  var result = [];
  for (var i = 0; i < n; ++i) result.push(elem);
  return result;
}

var criteria = repeat(lowercase, 4)
              .concat(repeat(uppercase, 4))
              .concat(repeat(numbers, 4));
console.log(makeRandomString(criteria));
soktinpk
  • 3,778
  • 2
  • 22
  • 33
0

Here is my solution :

var text = " ";
var numChars = "0123456789";
var upCaseChars="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var lowCaseChars="abcdefghijklmnopqrstuvwxyz";

for( var i=0; i < 4; i++ )
{  
    text += numChars.charAt(Math.floor(Math.random() * numChars.length));
    text += upCaseChars.charAt(Math.floor(Math.random() * upCaseChars.length));
    text += lowCaseChars.charAt(Math.floor(Math.random() * lowCaseChars.length));
}
console.log(text);

I think it should do the trick, you can test it here.

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
  • How does this help to _generate_ the string? – Evan Davis Oct 24 '14 at 22:50
  • @Mathletics Yes you are right I surely missed the main part of the question ! But I corrected the answer to fit the wanted solution. – cнŝdk Oct 25 '14 at 22:32
  • This always generates strings in the pattern `NUMBER UPPERCASE LOWERCASE NUMBER UPPERCASE LOWERCASE` so it's not really random, but depending on what exactly the OP is using this for, it's not a bad solution -- it's short and simple. – soktinpk Oct 26 '14 at 14:31
0

Following your same philosophy, you could try something like this. You will generate a random string with 4 characters of each group at least (so at least 12 characters), and up to the number of characters you specify as the parameter.

var LOWER_CASE_MASK = 'abcdefghijklmnopqrstuvwxyz';
var UPPER_CASE_MASK = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var NUMBER_MASK = '0123456789';
var ALL_MASK = LOWER_CASE_MASK + UPPER_CASE_MASK + NUMBER_MASK;

function randomString(length) {
  var result = '';
  for (var i = 0; i < 4; i++) {
    result += randomise(LOWER_CASE_MASK);
    result += randomise(UPPER_CASE_MASK);
    result += randomise(NUMBER_MASK);
  }
  for (var j = 0; j < length - 12; j++) {
    result += ALL_MASK[Math.round(Math.random() * (ALL_MASK.length - 1))];
  }
  return shuffle(result);
}

function randomise(string) {
  return string[Math.round(Math.random() * (string.length - 1))];
}

function shuffle(string) {
  var parts = string.split('');
  for (var i = parts.length; i > 0;) {
    var random = parseInt(Math.random() * i);
    var temp = parts[--i];
    parts[i] = parts[random];
    parts[random] = temp;
  }
  return parts.join('');
}

document.write(randomString(20));

The shuffle function is an implementation of the Fisher-Yates shuffle.

Plunker here.

Hope this helps.

Community
  • 1
  • 1
Pedro Lopez
  • 2,236
  • 2
  • 19
  • 27