I want to generate a random string that has to have 5 letters from a-z and 3 numbers.
How can I do this with JavaScript?
I\'ve got the following script, but
var Password = {
_pattern : /[a-zA-Z0-9_\-\+\.]/,
_getRandomByte : function()
{
// http://caniuse.com/#feat=getrandomvalues
if(window.crypto && window.crypto.getRandomValues)
{
var result = new Uint8Array(1);
window.crypto.getRandomValues(result);
return result[0];
}
else if(window.msCrypto && window.msCrypto.getRandomValues)
{
var result = new Uint8Array(1);
window.msCrypto.getRandomValues(result);
return result[0];
}
else
{
return Math.floor(Math.random() * 256);
}
},
generate : function(length)
{
return Array.apply(null, {'length': length})
.map(function()
{
var result;
while(true)
{
result = String.fromCharCode(this._getRandomByte());
if(this._pattern.test(result))
{
return result;
}
}
}, this)
.join('');
}
};
<input type='text' id='p'/><br/>
<input type='button' value ='generate' onclick='document.getElementById("p").value = Password.generate(16)'>
Ok so if I understand well you're trying to get a random string password which contains 5 letters and 3 numbers randomly positioned and so which has a length of 8 characters and you accept maj and min letters, you can do that with the following function:
function randPass(lettersLength,numbersLength) {
var j, x, i;
var result = '';
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var numbers = '0123456789';
for (i = 0; i < lettersLength; i++ ) {
result += letters.charAt(Math.floor(Math.random() * letters.length));
}
for (i = 0; i < numbersLength; i++ ) {
result += numbers.charAt(Math.floor(Math.random() * numbers.length));
}
result = result.split("");
for (i = result.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = result[i];
result[i] = result[j];
result[j] = x;
}
result = result.join("");
return result
}
function randPass(lettersLength,numbersLength) {
var j, x, i;
var result = '';
var letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var numbers = '0123456789';
for (i = 0; i < lettersLength; i++ ) {
result += letters.charAt(Math.floor(Math.random() * letters.length));
}
for (i = 0; i < numbersLength; i++ ) {
result += numbers.charAt(Math.floor(Math.random() * numbers.length));
}
result = result.split("");
for (i = result.length - 1; i > 0; i--) {
j = Math.floor(Math.random() * (i + 1));
x = result[i];
result[i] = result[j];
result[j] = x;
}
result = result.join("");
return result
}
console.log(randPass(5,3))
Forcing a fixed number of characters is a bad idea. It doesn't improve the quality of the password. Worse, it reduces the number of possible passwords, so that hacking by bruteforcing becomes easier.
To generate a random word consisting of alphanumeric characters, use:
var randomstring = Math.random().toString(36).slice(-8);
Math.random() // Generate random number, eg: 0.123456
.toString(36) // Convert to base-36 : "0.4fzyo82mvyr"
.slice(-8);// Cut off last 8 characters : "yo82mvyr"
Documentation for the Number.prototype.toString and string.prototype.slice methods.
And finally, without using floating point hacks:
function genpasswd(n) {
// 36 ** 11 > Number.MAX_SAFE_INTEGER
if (n > 10)
throw new Error('Too big n for this function');
var x = "0000000000" + Math.floor(Number.MAX_SAFE_INTEGER * Math.random()).toString(36);
return x.slice(-n);
}
Create a Password generator service called PassswordGeneratorService
import { Injectable } from '@angular/core';
@Injectable()
export class PasswordGeneratorService {
generatePassword(length:number,upper:boolean,numbers:boolean,symbols:boolean) {
const passwordLength = length || 12;
const addUpper = upper;
const addNumbers = numbers;
const addSymbols = symbols;
const lowerCharacters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
const upperCharacters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
const numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
const symbols = ['!', '?', '@'];
const getRandom = array => array[Math.floor(Math.random() * array.length)];
let finalCharacters = '';
if (addUpper) {
finalCharacters = finalCharacters.concat(getRandom(upperCharacters));
}
if (addNumbers) {
finalCharacters = finalCharacters.concat(getRandom(numbers));
}
if (addSymbols) {
finalCharacters = finalCharacters.concat(getRandom(symbols));
}
for (let i = 1; i < passwordLength - 3; i++) {
finalCharacters = finalCharacters.concat(getRandom(lowerCharacters));
}
return finalCharacters.split('').sort(() => 0.5 - Math.random()).join('');
}
}
don't forget to add the service on the module your using
@NgModule({
imports: [
CommonModule,
SharedModule,
CommonModule,
RouterModule.forChild(routes),
FormsModule,
ReactiveFormsModule,
FlexLayoutModule,
TranslateModule,
ExistingUserDialogModule,
UserDocumentsUploadDialogModule
],
declarations: [
UserListComponent,
EditUserDialogComponent,
UserEditorComponent
],
entryComponents: [
EditUserDialogComponent
],
providers: [
AuthService,
PasswordGeneratorService
]
})
export class UsersModule {
}
On you controller add a method which calls the generate password method inside the service and set the result on the password field
constructor(
private passwordGenerator: PasswordGeneratorService,
)
get newPassword() {
return this.password.get('newPassword');
}
generatePassword() {
this.newPassword.setValue(this.passwordGenerator.generatePassword(8,true,true,true));
}
Secure password with one upperCase char.
let once = false;
let newPassword = Math.random().toString(36).substr(2, 8).split('').map((char) => {
if(!Number(char) && !once){
once = true;
return char.toUpperCase();
}
return char;
}).join('');
console.log(newPassword)