# Premier programme

Nous allons créer un générateur de mots de passe.

# 1. Stocker les caractères autorisés

On peut stocker les caractères autorisés dans une chaîne de caractères (String) :

var availableChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_$!@'

Les Strings en JavaScript ne sont pas des tableaux (Array) de caractères, mais sont itérables, et on peut accéder au caractère d'un index particulier comme pour les tableaux :

var chaine = 'abcde' // Assignation de la chaîne de caractères 'abcde' à la variable chaine
var caractere = chaine[0] // Récupération du premier caractère (commence à 0) de la chaine
console.log(caractere) // 'a'  // Affichage du premier caractère
console.log(chaine[1]) // 'b'  // Affichage du deuxième caractère
console.log(chaine[2]) // 'c'  // Affichage du troisième caractère
(...)

# 2. Générer un nombre aléatoire

# La fonction Math.random()

La fonction Math.random() permet de générer un nombre aléatoire entre 0 et 1.

var randomNumber = Math.random()
console.log(randomNumber) // 0.8103176955269612

# La fonction Math.floor(number)

La fonction Math.floor(aNumber) permet de retourner la partie entière de aNumber :

var floatNumber = 12.455392049329
var integerNumber = Math.floor(floatNumber)
console.log(integerNumber) // 12

# Combiner les deux fonctions

En combinant les deux fonctions, on peut obtenir un générateur d'entier entre 0 et un autre entier (max) :

 var max = 42
 var randomBetween0AndMax = Math.floor(Math.random() * (max + 1))

# Rendre ce code réutilisable

Pour rendre ce code réutilisable, on peut le mettre dans une fonction :

// Déclaration d'une fonction getRandomNumber qui accepte un paramètre
function getRandomNumber (max) {
 // Calcule un nombre entier aléatoire entre 0 et max
 var randomNumber = Math.floor(Math.random() * (max + 1))
 // Renvoie ce nombre
 return randomNumber
}

Cette méthode pourra être utilisée de cette façon :

var max = 42
var randomNumber = getRandomNumber(max) // La variable randomNumber contiendra un nombre entier entre 0 et 42

# 3. Récupérer un caractère parmi les caractères autorisés

// Calcul du nombre maximum qu'on veut que la fonction retourne :
// entre 0 et la longueur de la chaine moins 1
var max = availableChars.length - 1

// Récupération d'un entier aléatoire entre 0 et max
var randomBetween0AndMax = getRandomNumber(max)

// Récupération du caractère qui est à l'index randomBetween0AndMax
// de la chaine de caractère availableChars
var randomChar = availableChars[randomBetween0AndMax]

// Affichage du caractère retourné dans la console
console.log(randomChar) // "Y"

# 4. Utiliser une boucle pour obtenir une chaîne aléatoire

var max = availableChars.length - 1

// Initialisation de la variable randomString à chaîne vide ''
var randomString = ''

// Tant que la chaîne randomString fait moins de 12 caractères...
while (randomString.length < 12) {
 // ...récupération d'un nombre aléatoire...
 var randomBetween0AndMax = getRandomNumber(max)
 // ...et ajout à la chaîne randomString du nouveau caractère à l'index randomBetween0AndMax
 randomString += availableChars[randomBetween0AndMax] // Concaténation avec l'opérateur +=
}

// Affichage de la chaîne générée
console.log(randomString) // "9fMyFqMfi$le"

# 5. Refactorer pour en faire un code réutilisable

Afin que le code soit réutilisable, il doit être mis dans une fonction :

// Déclaration de la fonction getRandomString qui prend un paramètre :
// le nombre de caractère que doit avoir la chaîne finale
function getRandomString (stringLength) {
 // Définition des caractères autorisés dans la chaîne finale
 var availableChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_$!@'
 var max = availableChars.length - 1

 var randomString = ''
 while (randomString.length < stringLength) {
   var randomBetween0AndMax = getRandomNumber(max)
   randomString += availableChars[randomBetween0AndMax]
 }

 return randomString
}

// Invocation de la fonction avec 10 pour argument
var randomStr = getRandomString(10)

// Affichage de la chaîne générée
console.log(randomString) // "Nme3r4@6P!" : une chaîne aléatoire de 10 caractères

# 6. Refactorer pour en faire un code encore plus réutilisable

// Déclaration de la fonction getRandomString qui prend deux paramètres :
// 1. le nombre de caractère que doit avoir la chaîne finale
// 2. les caractères autorisés dans la chaîne finale
function getRandomString (stringLength, availableChars) {
 var max = availableChars.length - 1

 var randomString = ''
 while (randomString.length < stringLength) {
   var randomBetween0AndMax = getRandomNumber(max)
   randomString += availableChars[randomBetween0AndMax]
 }

 return randomString
}

var availableChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_$!@'

var randomString = getRandomString(8, availableChars)
console.log(randomString)

# 7. Ajouter des valeurs par défaut pour les paramètres

On peut aller encore plus loin en mettant des valeurs par défaut pour les paramètres de la fonction :

# Version ES6

Depuis ES6, une nouvelle syntaxe existe pour les valeurs par défaut des arguments (opens new window).

var defaultAvailableChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_$!@'

function getRandomString (stringLength = 8, availableChars = defaultAvailableChars) { // "Default parameters"

 var max = availableChars.length - 1

 var randomString = ''
 
 while (randomString.length < stringLength) {
   var randomBetween0AndMax = getRandomNumber(max)
   randomString += availableChars[randomBetween0AndMax]
 }

 return randomString
}

# Utilisation

La fonction est utilisable de la façon suivante :


var random8CharString = getRandomString()
console.log(random8CharString) // 'QQSoImrA'

var random12CharString = getRandomString(12)
console.log(random12CharString) // 'WQoXk_k_sW$Z'

var random15FiguresString = getRandomString(15, '1234567890')
console.log(random15FiguresString) // '681425434703558'

var random8FiguresString = getRandomString(undefined, '1234567890') // undefined sera remplacé par 8
console.log(random8FiguresString) // '38444115'

# Résultat final

function getRandomNumber (max) {
 var randomNumber = Math.floor(Math.random() * (max + 1))
 return randomNumber
}

var defaultAvailableChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_$!@'

function getRandomString (stringLength = 8, availableChars = defaultAvailableChars) {
 var max = availableChars.length - 1

 var randomString = ''
 
 while (randomString.length < stringLength) {
   var randomBetween0AndMax = getRandomNumber(max)
   randomString += availableChars[randomBetween0AndMax]
 }

 return randomString
}

# Bonus : version un-peu-trop-malin

On peut réduire le code en très peu de lignes, mais ce n'est pas à conseiller : le code est très peu lisible, incompréhensible pour le novice.

var defaultAvailableChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_$!@'

function getRandomNumber (max) {
 return Math.floor(Math.random() * (max + 1))
}

function getRandomStringSioux (length = 8, availableChars = defaultAvailableChars) {
 var max = availableChars.length - 1
 return Array.from({length}).reduce(acc => acc + availableChars[getRandomNumber(max)], '')
}

Explications :

var length = 8
var obj = {length}

Équivaut à :

var length = 8
var obj = {length: length}

Or l'objet {length: 8} est un Array-like, et en utilisant la fonction Array.from({length}) (opens new window) il devient un Array avec 8 éléments (chaque élément aura pour valeur undefined), sur lequel on peut itérer, et donc sur lequel on peut utiliser la méthode reduce() (cf. MDN (opens new window)).

On passe ici à cette méthode reduce() un argument qui est une fonction fléchée (opens new window) qui prend en premier paramètre l'accumulateur de la fonction (acc) et renvoie l'accumulateur (acc) concaténé (+) avec un nouveau caractère choisi parmi les caractères autorisés (availableChars[getRandomNumber(max)]).