Ajames
Ajames

Reputation: 53

How can I randomly capitalise letters in a string

I'm sorry if this has been asked before, but I can't seem to find the right answer.

I'm trying to create a random password generator using Javascript. I've set meself 4 basic requirements:

  1. Must contain letters, numbers and special characters
  2. Must be 14 characters
  3. Must have upper and lower case lettering
  4. Must log the result as a string

Here is what I have:

var characters = 'abcdefghijklmnoqrstuvwxyz0123456789?<>!"£$%^&*()-+./';
var results = '';
var length = characters.length;

function randomPassword() {

for (i=0; i<=13; i++) {
    var mix = characters.charAt(Math.floor(Math.random() * length));        
    var newString = results += mix;
    }
    console.log(newString);
}

randomPassword();

The code above passes all of my requirements apart from the upper and lower case letters. Is there a way to randomly capitalise some of the letters in my string? I've tried playing with .toUpperCase() in the same way I have to create my 'mix' variable, but I can't work out how to do it.

This isn't for any real life projects. I'm just using this as a way to try to learn Javascript, so any advice would be greatly appreciated :)

Thanks!

Upvotes: 0

Views: 1950

Answers (4)

Manoj Rana
Manoj Rana

Reputation: 3460

It's my way to capitalise some random characters from a given string.

const myString = 'manoj_rana';

const randomCapitaliseString = [...myString].map(c => Math.random() < .6 ? c : c.toUpperCase()).join('');

Upvotes: 0

Fabrizio Calderan
Fabrizio Calderan

Reputation: 123397

if you need to have both upper and lower characters and numbers and special chars, a random choice from a single characters variable can't always ensure this requirement.

In the version below I've created an array of characters subsets, where every required subset is included at least 3 times in the final password.

Simple version

var alphabet = [
  'abcdefghijklmnoqrstuvwxyz',
  'ABCDEFGHIJKLMNOQRSTUVWXYZ',
  '0123456789',
  '?<>!"£$%^&*()-+./'
];

password = '';
 
for (var i = 0; i < 14; i++) {
   var subset = alphabet[i%4];
   password += subset[Math.floor(Math.random() * subset.length)]
}

console.log(password);


Safer version

here both the subsets and the password are scrambled using a JS implementation of Fisher-Yates algorithm so to avoid predictable generations.

function shuffle_Fisher_Yates(array) {

  var currentIndex = array.length, temporaryValue, randomIndex;

  while (0 !== currentIndex) {

    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}


var alphabet = shuffle_Fisher_Yates([
  'abcdefghijklmnoqrstuvwxyz',
  'ABCDEFGHIJKLMNOQRSTUVWXYZ',
  '0123456789',
  '?<>!"£$%^&*()-+./'
]);

password = '';
 
for (var i = 0; i < 14; i++) {
   var subset = alphabet[i%4];
   password += subset[Math.floor(Math.random() * subset.length)]
}

console.log(shuffle_Fisher_Yates(password.split('')).join(''));

Upvotes: 0

Harsimranjit Singh
Harsimranjit Singh

Reputation: 245

your code is good and correct just make a simple improvement as mentioned below. you can achieve your goal.

var characters = 'abcdefghijklmnoqrstuvwxyz0123456789?<>!"£$%^&*()-+./';
     var results = '';
     var length = characters.length;

  function randomPassword() {
      var check = 2;
      for (i=0; i<=13; i++) {
        var mix = characters.charAt(Math.floor(Math.random() * length));     
        if (mix.match(/[a-z]/i) && check>0) {
          mix =  mix.toUpperCase();
          check --;
        }
     var newString = results += mix;
    }
    console.log(newString);
   }
  randomPassword();

    var characters = 'abcdefghijklmnoqrstuvwxyz0123456789?<>!"£$%^&*()-+./';
     var results = '';
     var length = characters.length;

  function randomPassword() {
      var check = 2;
      for (i=0; i<=13; i++) {
        var mix = characters.charAt(Math.floor(Math.random() * length));     
        if (mix.match(/[a-z]/i) && check>0) {
          mix =  mix.toUpperCase();
          check --;
        }
     var newString = results += mix;
    }
    console.log(newString);
   }
  randomPassword();

Upvotes: 1

Anas M.I
Anas M.I

Reputation: 582

Here's one way

myString.toLowerCase().split('').map(function(c){
return Math.random() < .5? c : c.toUpperCase();
}).join('');

Upvotes: 4

Related Questions