Create your Password Generator in Jetpack Compose | Part 2 | PwdGen

WhiteBatCodes
3 min readMay 25, 2023

Password generators are commonly used to generate strong passwords for your accounts. This application is for you to make your own custom Password generator app and even store those passwords in a secure location for later usage.

In Part 1, we have created the UI and now we are left with the logic to implement. We will configure the password generator, the logic for the buttons : Copy and Generate. Let’s get to it!

Let’s create the following packages : models.password.content

In the package models.password we’ll create a Kotlin class : PasswordGenerator.kt

It will be a data class with two parameters : password Size and password Content .The password Content is basically the password composition : Uppercase, Lowercase, Numeric & Custom Password.

We’ll add a function called generatePassword that will return to us the generated password. The class should look like this :

data class PasswordGenerator(
var passwordSize: Int,
var passwordContent: ArrayList<PasswordContent>
) {

fun generatePassword() : String{
var result = ""

for(i in 0..passwordSize){
val index = (Math.random()*passwordContent.size).toInt()
result+= passwordContent[index].getRandom()
}
return result
}
}

Let’s go into the content package and create an interface PasswordContent:

package com.whitebatcodes.passwordvault.models.password.contents

interface PasswordContent {

var content : String

fun getRandom(): Char{
val index = (Math.random()*content.length).toInt()
return content[index]
}

}

This interface will hold a single password composition and it has the method getRandom() That returns a random Char from the content String.

Now let’s implement this method using few Classes. In this context, I will be using singletons for the 3 classes : UpperPwdContent, LowerPwdContent & NumericPwdContent They will look like so :

package com.whitebatcodes.passwordvault.models.password.contents

data class LowerPwdContentImpl(override var content: String = "abcdefghijklmnopqrstuvwxyz") : PasswordContent



object LowerPwdContent {
private var instance : PasswordContent = LowerPwdContentImpl()

fun getInstance() : PasswordContent{
return instance
}
}
package com.whitebatcodes.passwordvault.models.password.contents

data class UpperPwdContentImpl(override var content: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ") : PasswordContent


object UpperPwdContent {
private var instance : PasswordContent = UpperPwdContentImpl()

fun getInstance() : PasswordContent{
return instance
}
}
package com.whitebatcodes.passwordvault.models.password.contents

data class NumericPwdContentImpl(override var content: String = "1234567890") : PasswordContent

object NumericPwdContent {
private var instance : PasswordContent = NumericPwdContentImpl()

fun getInstance() : PasswordContent{
return instance
}
}

The Custom password content will not be static, as it will be built as needed:

package com.whitebatcodes.passwordvault.models.password.contents

data class CustomPwdContent(override var content: String = "?!@,-_&#(){}[]") : PasswordContent

Now that we have everything ready, let’s drop in design pattern : Builder in our PasswordGenerator class to build the password generator as needed. The class should look like this:

data class PasswordGenerator(
var passwordSize: Int,
var passwordContent: ArrayList<PasswordContent>
) {

fun generatePassword() : String{
var result = ""

for(i in 0..passwordSize){
val index = (Math.random()*passwordContent.size).toInt()
result+= passwordContent[index].getRandom()
}
return result
}

class Builder{
private var instance = PasswordGenerator(8, ArrayList())

fun addUpper(hasUpper : Boolean) : Builder{
if(hasUpper) instance.passwordContent.add(UpperPwdContent.getInstance())
return this
}
fun addLower(hasLower : Boolean) : Builder{
if(hasLower) instance.passwordContent.add(LowerPwdContent.getInstance())
return this
}
fun addNumeric(hasNumeric : Boolean) : Builder{
if(hasNumeric) instance.passwordContent.add(NumericPwdContent.getInstance())
return this
}
fun addCustom(hasCustom : Boolean, custom : CustomPwdContent) : Builder{
if(hasCustom) instance.passwordContent.add(custom)
return this
}

fun setSize(pwdSize : Int): Builder{
instance.passwordSize = pwdSize
return this
}

fun build() : PasswordGenerator{
return instance
}
}
}

Now that the logic is ready, we’ll have to update the PasswordGeneratorActivity. In the generate button, inside the onClick parameter, let’s add the following :

 val pwdGen = PasswordGenerator.Builder()
.addUpper(isUpper)
.addLower(isLower)
.addNumeric(isNumeric)
.addCustom(isCustom, CustomPwdContent(customPasswordSetting))
.setSize(if (passwordSize.isEmpty()) 8 else passwordSize.toInt())
.build()

generatedPassword = pwdGen.generatePassword()

In the copy button, we’ll need a context to call the clipboard. So add the following variable near the state variables and then add the following code :

val context = LocalContext.current
val clipboardManager = getSystemService(
context,
ClipboardManager::class.java
) as ClipboardManager
val clipData = ClipData.newPlainText("text", generatedPassword)
clipboardManager.setPrimaryClip(clipData)

Toast.makeText(context, "Password Copied",Toast.LENGTH_SHORT).show()

And we’re done! You can run your application to see the generated password.

The GitHub code can be found here : GitHub repo

Here’s a YouTube video if you want to follow the same steps more visually :

You can read about part 1 here : Create your Password Generator in Jetpack Compose | Part 1 | Interface

Part 3 can be found here : Create your Password Generator in Jetpack Compose | Part 3 | Password Edit UI

--

--

WhiteBatCodes

A software engineer👨‍💻 with a passion for IT 📱💻 and cyber security 🔐.