Creating a Password Generator

Published on:

Disclaimer. This is not intended for use in a production environment to create your passwords. My use case for this is to actually generate one off use codes such as One Time Pass Codes. This is not the most secure as the list of words is quite small, and will leave you open to a potential dictionary attack.

Password generation is something we all think about doing at some point, but how can we go about doing it - and making these passwords easy to remember and secure?

In this tutorial, I will walk you through how I recently built a password generator for fun and what my thoughts were. I created it for more than just Laravel but as a framework agnostic approach that I could use within Laravel easily.

When using a create password tool, you often get a selection of words joined together with a dash. I wanted to make something I could use and remember with relative ease, but with the option to make the passwords more “secure” by switching letters for numbers in places.

Let’s get our code on!

We first want to define a standard interface that our generator will want to implement - this will allow us to use it within Laravel, outside of Laravel, and wherever we want to use it.

interface GeneratorContract
{
    /**
     * @return string
     */
    public function generate(): string;

    /**
     * @return string
     */
    public function generateSecure(): string;
}

We want our implementation to have two possible approaches, generate a random password using memorable words - and another option to generate the same thing that may be seen as more secure. A perfect example of this would be:

flying-fish-swimming-lizard - memorable fly1ng-f1sh-sw1mm1ng-l1z4rd - “secure”

To achieve this, we will need to create a way for words to be generated. We will need Nouns and Adjectives, meaning we need to create another contract to follow. This contract will be a way to fetch a random word from a registered list either in a standard approach or in our required secure approach.

interface ListContract
{
    public function random(): string;

    public function secure(): string;
}

Both methods on this contract will achieve roughly the same thing, the only difference is that with one of them, we will do a little more processing before returning. Let’s dive into the code to see how this can work.

We know that we require a list of nouns and a list of adjectives, and both are going to do the same thing in terms of behavior. In the future, we may slightly change this so that we get verbs included as well, but for now, we will focus on nouns and adjectives. To achieve this, I will use a PHP Trait to add shared behavior to each implementation.

trait HasWords
{
    /**
     * @param array $words
     */
    public function __construct(
        private readonly array $words,
    ) {
    }

    public function random(): string
    {
        return $this->words[array_rand($this->words)];
    }
}

To begin with, we create the trait, where we know that our implementation will want to be created with an array of words. Then we add the method for selecting a random item from this array. This will allow us to build our standard memorable password by calling this a few times and concatenating the results. Let’s add this to the two implementations that we need to create.

final class AdjectiveList implements ListContract
{
    use HasWords;
}


final class NounList implements ListContract
{
    use HasWords;
}

Our two implementations will allow us to generate half of what we need. We must consider how we want to create our “secure” passwords next. Let us revisit the trait we created.

trait HasWords
{
    /**
     * @param array $words
     */
    public function __construct(
        private readonly array $words,
    ) {
    }

    public function random(): string
    {
        return $this->words[array_rand($this->words)];
    }

    public function secure(): string
    {
        $word = $this->random();

        $asArray = str_split($word);

        $secureArray = array_map(
            callback: fn (string $item): string => $this->convertToNumerical($item),
            array: $asArray,
        );

        return implode('', $secureArray);
    }

    public function convertToNumerical(string $item): string
    {
        return match ($item) {
            'a' => '4',
            'e' => '3',
            'i' => '1',
            'o' => '0',
            default => $item,
        };
    }
}

So how do this work? As a “secure” password, we still want to fetch a random word from our list, but we need to do some additional processing. We split the word into its core letters to have an array. We can then map over each letter - and call our convert method to update the input. Our convert method is a simple match statement that we can use to map the input to the output, so we are controlling how these are written. I have mapped these here to a typical approach you may find where the number representation looks like the letter representation - allowing us to have a memorable password still.

Our list control now works, and we can create a list of nouns and adjectives - that are injected into the constructors. We can fetch the word directly or pass it through a converter to make it more “secure”. Our next step is to look at the implementation of our generator. So far, we only have implementations for the lists themselves. Let’s look at some more code.

final class PasswordGenerator implements GeneratorContract
{
    public function __construct(
        private readonly ListContract $nouns,
        private readonly ListContract $adjectives,
    ) {
    }

    public function generate(): string
    {
        return $this->build(
            $this->nouns->random(),
            $this->adjectives->random(),
            $this->nouns->random(),
            $this->adjectives->random(),
        );
    }

    public function generateSecure(): string
    {
        return $this->build(
            $this->nouns->secure(),
            $this->adjectives->secure(),
            $this->nouns->secure(),
            $this->adjectives->secure(),
        );
    }

    private function build(string ...$parts): string
    {
        return implode('-', $parts);
    }
}

Our password generator takes the two list implementations into its constructor so that we can access them. We then implement the two methods for generating passwords: memorable and secure.

For each approach, we call a method internally that will allow us to build the password by imploding the array with a joining string. If we want to extend this to more words, we must pass in more random words.

Our contract does not need to know about the build method as that is an implementation detail. We could extend this method to customize the joining character - but I will leave that to your implementation should you want to.

As an additionally added extra, we will now create a service provider and facade so that you can quickly call or inject this into your application code. This part is Laravel only, though. Up until this point, we have focused on framework-independent code.

final class PackageServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(
            abstract: GeneratorContract::class,
            concrete: fn (): GeneratorContract => new PasswordGenerator(
                nouns: new NounList(
                    words: (array) config('password-generator.nouns'),
                ),
                adjectives: new AdjectiveList(
                    words: (array) config('password-generator.adjectives'),
                ),
            ),
        );
    }

    public function boot(): void
    {
        if ($this->app->runningInConsole()) {
            $this->publishes(
                paths: [
                    __DIR__ . '/../../config/password-generator.php',
                    config_path('password-generator.php'),
                ],
                groups: 'password-generator-config',
            );
        }
    }
}

Here we are loading our configuration, which will house the nouns and adjectives we want to use in our password generator. We also provide a set of instructions to Laravel about how we wish to load our implementation from the container.

Now the facade will work in the same way but will resolve the implementation from the container allowing you to statically call the methods you wish to call.

/**
 * @method static string generate()
 * @method static string generateSecure()
 *
 * @see GeneratorContract
 */
final class Generator extends Facade
{
    protected static function getFacadeAccessor(): string
    {
        return GeneratorContract::class;
    }
}

Our facade returns the contract that we have used to bind the implementation and has docblocks stating what methods are available and the return types it expects.

All we now need to do is call the password generator, and we can provide randomly generated passwords for our users.

Generator::generate(); // flying-fish-swimming-lizard
Generator::generateSecure(); // fly1ng-f1sh-sw1mm1ng-l1z4rd

I have created a package that delivers this code above, which has a little more code should you wish to dive into the example a little more. You can find the repository for this here: https://github.com/JustSteveKing/password-generator

What people say about me

Aaron Francis

Aaron Francis

Founder @ Try Hard Studies

Steve is one of the most thorough and thoughtful educators I've seen. He puts in a ton of effort and it clearly shows.
Alex Six

Alex Six

Head of Developer Relations @ Filament PHP

Steve is the teacher you wish you had in school. He’s informative, entertaining, and passionate about what he does. I’m always excited to see more of Steve’s content!
Brent Roose

Brent Roose

Developer Advocate @ jetBrains

To me, there's one word that comes to mind: 'passion'. There are only a handful of people with the same passion for programming as Steve.
Chris Miller

Chris Miller

Lead Developer @ MMS Marketing

Steve is a great developer with a wealth of knowledge that has contributed to many projects we have. His passion for API means we benefit from his aim for the best
Davor Minchorov

Davor Minchorov

Senior PHP Engineer @ Adeva

Steve is an awesome guy who knows a thing or two about APIs. I’ve learned so much from his content on his YouTube channel as well as his API video course.
Eric Barnes

Eric Barnes

Founder @ Laravel News

Steve is an awesome writer and communicator, he can take complex problems and communicate them in a way that anyone can understand.
Gary Clarke

Gary Clarke

YouTuber @ Gary Clarke Tech

Steve is highly engaging and an expert in what he does. I bookmark everything he publishes and refer back to it on a regular basis. The API king!
Aaron Francis

Aaron Francis

Founder @ Try Hard Studies

Steve is one of the most thorough and thoughtful educators I've seen. He puts in a ton of effort and it clearly shows.
Alex Six

Alex Six

Head of Developer Relations @ Filament PHP

Steve is the teacher you wish you had in school. He’s informative, entertaining, and passionate about what he does. I’m always excited to see more of Steve’s content!
Brent Roose

Brent Roose

Developer Advocate @ jetBrains

To me, there's one word that comes to mind: 'passion'. There are only a handful of people with the same passion for programming as Steve.
Chris Miller

Chris Miller

Lead Developer @ MMS Marketing

Steve is a great developer with a wealth of knowledge that has contributed to many projects we have. His passion for API means we benefit from his aim for the best
Davor Minchorov

Davor Minchorov

Senior PHP Engineer @ Adeva

Steve is an awesome guy who knows a thing or two about APIs. I’ve learned so much from his content on his YouTube channel as well as his API video course.
Eric Barnes

Eric Barnes

Founder @ Laravel News

Steve is an awesome writer and communicator, he can take complex problems and communicate them in a way that anyone can understand.
Gary Clarke

Gary Clarke

YouTuber @ Gary Clarke Tech

Steve is highly engaging and an expert in what he does. I bookmark everything he publishes and refer back to it on a regular basis. The API king!
Aaron Francis

Aaron Francis

Founder @ Try Hard Studies

Steve is one of the most thorough and thoughtful educators I've seen. He puts in a ton of effort and it clearly shows.
Alex Six

Alex Six

Head of Developer Relations @ Filament PHP

Steve is the teacher you wish you had in school. He’s informative, entertaining, and passionate about what he does. I’m always excited to see more of Steve’s content!
Brent Roose

Brent Roose

Developer Advocate @ jetBrains

To me, there's one word that comes to mind: 'passion'. There are only a handful of people with the same passion for programming as Steve.
Chris Miller

Chris Miller

Lead Developer @ MMS Marketing

Steve is a great developer with a wealth of knowledge that has contributed to many projects we have. His passion for API means we benefit from his aim for the best
Davor Minchorov

Davor Minchorov

Senior PHP Engineer @ Adeva

Steve is an awesome guy who knows a thing or two about APIs. I’ve learned so much from his content on his YouTube channel as well as his API video course.
Eric Barnes

Eric Barnes

Founder @ Laravel News

Steve is an awesome writer and communicator, he can take complex problems and communicate them in a way that anyone can understand.
Gary Clarke

Gary Clarke

YouTuber @ Gary Clarke Tech

Steve is highly engaging and an expert in what he does. I bookmark everything he publishes and refer back to it on a regular basis. The API king!
Aaron Francis

Aaron Francis

Founder @ Try Hard Studies

Steve is one of the most thorough and thoughtful educators I've seen. He puts in a ton of effort and it clearly shows.
Alex Six

Alex Six

Head of Developer Relations @ Filament PHP

Steve is the teacher you wish you had in school. He’s informative, entertaining, and passionate about what he does. I’m always excited to see more of Steve’s content!
Brent Roose

Brent Roose

Developer Advocate @ jetBrains

To me, there's one word that comes to mind: 'passion'. There are only a handful of people with the same passion for programming as Steve.
Chris Miller

Chris Miller

Lead Developer @ MMS Marketing

Steve is a great developer with a wealth of knowledge that has contributed to many projects we have. His passion for API means we benefit from his aim for the best
Davor Minchorov

Davor Minchorov

Senior PHP Engineer @ Adeva

Steve is an awesome guy who knows a thing or two about APIs. I’ve learned so much from his content on his YouTube channel as well as his API video course.
Eric Barnes

Eric Barnes

Founder @ Laravel News

Steve is an awesome writer and communicator, he can take complex problems and communicate them in a way that anyone can understand.
Gary Clarke

Gary Clarke

YouTuber @ Gary Clarke Tech

Steve is highly engaging and an expert in what he does. I bookmark everything he publishes and refer back to it on a regular basis. The API king!
Jack Ellis

Jack Ellis

Co-Founder @ Fathom Analytics

Steve is one of the top API experts in the world and has been teaching our community for years.
Laravel Jutsu

Laravel Jutsu

YouTuber @ Laravel Jutsu

Steve has a profound mastery of APIs and a public-serving teaching approach.
Luke Downing

Luke Downing

Educator @ Laracasts

Steve is a stream of knowledge. If you like clean, strict code and silky APIs, there’s nobody I’d sooner turn to for advice!
Sam Carré

Sam Carré

Head of Engineering @ Plannr CRM

Steve’s enthusiasm and positive attitude makes his educational content super easy to digest and makes learning new tools and languages really fun.
Peter Thomson

Peter Thomson

Chief Technology Officer @ Ice House Ventures

Steve is an absolute weapon. We came for the APIs but we stayed for the clean code, robust systems architecture and deep knowledge of Laravel conventions. Steve made our code faster, more stable and easier to maintain ourselves in the future.
Stephen Rees-Carter

Stephen Rees-Carter

Friendly Hacker @ Valorin Security

Steve is one of my favourite people. He has a huge passion for teaching developers about APIs and good coding practices.
Steven Tey

Steven Tey

Founder @ Dub.co

Steve brings knowledge and passion to the community, with easy to follow content that adds real value to any company that uses him.
Jack Ellis

Jack Ellis

Co-Founder @ Fathom Analytics

Steve is one of the top API experts in the world and has been teaching our community for years.
Laravel Jutsu

Laravel Jutsu

YouTuber @ Laravel Jutsu

Steve has a profound mastery of APIs and a public-serving teaching approach.
Luke Downing

Luke Downing

Educator @ Laracasts

Steve is a stream of knowledge. If you like clean, strict code and silky APIs, there’s nobody I’d sooner turn to for advice!
Sam Carré

Sam Carré

Head of Engineering @ Plannr CRM

Steve’s enthusiasm and positive attitude makes his educational content super easy to digest and makes learning new tools and languages really fun.
Peter Thomson

Peter Thomson

Chief Technology Officer @ Ice House Ventures

Steve is an absolute weapon. We came for the APIs but we stayed for the clean code, robust systems architecture and deep knowledge of Laravel conventions. Steve made our code faster, more stable and easier to maintain ourselves in the future.
Stephen Rees-Carter

Stephen Rees-Carter

Friendly Hacker @ Valorin Security

Steve is one of my favourite people. He has a huge passion for teaching developers about APIs and good coding practices.
Steven Tey

Steven Tey

Founder @ Dub.co

Steve brings knowledge and passion to the community, with easy to follow content that adds real value to any company that uses him.
Jack Ellis

Jack Ellis

Co-Founder @ Fathom Analytics

Steve is one of the top API experts in the world and has been teaching our community for years.
Laravel Jutsu

Laravel Jutsu

YouTuber @ Laravel Jutsu

Steve has a profound mastery of APIs and a public-serving teaching approach.
Luke Downing

Luke Downing

Educator @ Laracasts

Steve is a stream of knowledge. If you like clean, strict code and silky APIs, there’s nobody I’d sooner turn to for advice!
Sam Carré

Sam Carré

Head of Engineering @ Plannr CRM

Steve’s enthusiasm and positive attitude makes his educational content super easy to digest and makes learning new tools and languages really fun.
Peter Thomson

Peter Thomson

Chief Technology Officer @ Ice House Ventures

Steve is an absolute weapon. We came for the APIs but we stayed for the clean code, robust systems architecture and deep knowledge of Laravel conventions. Steve made our code faster, more stable and easier to maintain ourselves in the future.
Stephen Rees-Carter

Stephen Rees-Carter

Friendly Hacker @ Valorin Security

Steve is one of my favourite people. He has a huge passion for teaching developers about APIs and good coding practices.
Steven Tey

Steven Tey

Founder @ Dub.co

Steve brings knowledge and passion to the community, with easy to follow content that adds real value to any company that uses him.
Jack Ellis

Jack Ellis

Co-Founder @ Fathom Analytics

Steve is one of the top API experts in the world and has been teaching our community for years.
Laravel Jutsu

Laravel Jutsu

YouTuber @ Laravel Jutsu

Steve has a profound mastery of APIs and a public-serving teaching approach.
Luke Downing

Luke Downing

Educator @ Laracasts

Steve is a stream of knowledge. If you like clean, strict code and silky APIs, there’s nobody I’d sooner turn to for advice!
Sam Carré

Sam Carré

Head of Engineering @ Plannr CRM

Steve’s enthusiasm and positive attitude makes his educational content super easy to digest and makes learning new tools and languages really fun.
Peter Thomson

Peter Thomson

Chief Technology Officer @ Ice House Ventures

Steve is an absolute weapon. We came for the APIs but we stayed for the clean code, robust systems architecture and deep knowledge of Laravel conventions. Steve made our code faster, more stable and easier to maintain ourselves in the future.
Stephen Rees-Carter

Stephen Rees-Carter

Friendly Hacker @ Valorin Security

Steve is one of my favourite people. He has a huge passion for teaching developers about APIs and good coding practices.
Steven Tey

Steven Tey

Founder @ Dub.co

Steve brings knowledge and passion to the community, with easy to follow content that adds real value to any company that uses him.

© 2025 JustSteveKing. All rights reserved.