创建密码生成器

发布于 作者:

Creating a Password Generator image

密码生成是我们每个人在某个时候都会想到的事情,但我们如何才能做到这一点,并使这些密码易于记忆且安全呢?

在本教程中,我将带您了解我最近如何为乐趣构建密码生成器以及我的想法。我创建它不仅仅是为了 Laravel,而是作为一种与框架无关的方法,我可以轻松地在 Laravel 中使用它。

在使用创建密码工具时,您通常会得到一些用连字符连接在一起的单词。我想制作一些我可以使用并相对容易记住的东西,但可以选择通过在某些地方将字母替换为数字来使密码更“安全”。

让我们开始写代码吧!

我们首先要定义一个标准接口,我们的生成器将要实现它——这将允许我们在 Laravel 中、Laravel 之外以及任何我们想要使用它的地方使用它。

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

我们希望我们的实现有两种可能的方法,一种是使用令人难忘的单词生成随机密码,另一种是生成看起来更安全的相同密码。一个完美的例子是

flying-fish-swimming-lizard - 令人难忘的 fly1ng-f1sh-sw1mm1ng-l1z4rd - “安全”

为了实现这一点,我们需要创建一种生成单词的方法。我们需要名词形容词,这意味着我们需要创建另一个要遵循的契约。这个契约将是一种从注册列表中获取随机单词的方法,无论是标准方法还是我们所需的安全方法。

interface ListContract
{
public function random(): string;
 
public function secure(): string;
}

这个契约上的两种方法都将实现大致相同的事情,唯一的区别是其中一种方法在返回之前我们会进行一些额外的处理。让我们深入代码,看看这是如何工作的。

我们知道我们需要一个名词列表和一个形容词列表,它们在行为方面都是一样的。将来,我们可能会稍微改变一下,这样我们也可以包含动词,但现在,我们将专注于名词和形容词。为了实现这一点,我将使用 PHP 特性将共享行为添加到每个实现中。

trait HasWords
{
/**
* @param array $words
*/
public function __construct(
private readonly array $words,
) {
}
 
public function random(): string
{
return $this->words[array_rand($this->words)];
}
}

首先,我们创建特性,我们知道我们的实现将使用单词数组创建。然后,我们添加从这个数组中选择随机项目的方法。这将允许我们通过多次调用此方法并将结果连接起来来构建我们标准的令人难忘的密码。让我们将它添加到我们需要创建的两个实现中。

final class AdjectiveList implements ListContract
{
use HasWords;
}
 
 
final class NounList implements ListContract
{
use HasWords;
}

我们的两个实现将允许我们生成我们需要的一半东西。接下来,我们必须考虑如何创建我们的“安全”密码。让我们重新审视我们创建的特性。

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,
};
}
}

那么如何做到这一点呢?作为“安全”密码,我们仍然希望从我们的列表中获取一个随机单词,但我们需要进行一些额外的处理。我们将单词拆分为其核心字母,以获得一个数组。然后,我们可以遍历每个字母,并调用我们的 convert 方法来更新输入。我们的 convert 方法是一个简单的匹配语句,我们可以用它来将输入映射到输出,因此我们正在控制这些内容的写入方式。我在这里将它们映射到您可能发现的典型方法,其中数字表示看起来像字母表示——让我们仍然可以拥有令人难忘的密码。

我们的列表控制现在起作用了,我们可以创建一个名词和形容词列表——它们被注入构造函数中。我们可以直接获取单词,或者将其传递给转换器以使其更“安全”。我们的下一步是看看我们生成器的实现。到目前为止,我们只有列表本身的实现。让我们看更多代码。

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);
}
}

我们的密码生成器将两个列表实现带入其构造函数中,以便我们可以访问它们。然后,我们实现生成密码的两种方法:令人难忘的和安全的。

对于每种方法,我们都会在内部调用一个方法,该方法将允许我们通过使用连接字符串将数组连接起来来构建密码。如果我们想将其扩展到更多单词,我们必须传入更多随机单词。

我们的契约不需要知道build方法,因为这是一个实现细节。我们可以扩展此方法来自定义连接字符,但我将留给您自己实现,如果您需要的话。

作为额外的附加内容,我们现在将创建一个服务提供者和外观,以便您可以快速调用它或将其注入到您的应用程序代码中。不过,这部分只适用于 Laravel。到目前为止,我们一直专注于与框架无关的代码。

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',
);
}
}
}

在这里,我们正在加载我们的配置,它将容纳我们希望在密码生成器中使用的名词和形容词。我们还向 Laravel 提供了一组关于如何从容器中加载我们的实现的说明。

现在,外观将以相同的方式工作,但会从容器中解析实现,允许您静态调用您希望调用的方法。

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

我们的外观返回我们用来绑定实现的契约,并且具有说明可用的方法及其预期返回类型的文档块。

现在我们只需要调用密码生成器,我们就可以为我们的用户提供随机生成的密码。

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

我创建了一个包来提供上面的代码,它还有更多代码,如果您希望更深入地了解示例,可以参考。您可以在此处找到此代码库:https://github.com/JustSteveKing/password-generator

免责声明。这并不适合在生产环境中使用来创建您的密码。我使用这个的用例实际上是生成一次性使用代码,例如一次性密码。这不是最安全的,因为单词列表非常小,会让您容易受到潜在的字典攻击。

Steve McDougall photo

技术作家,Laravel 新闻Treblle 的开发者倡导者。API 专家,经验丰富的 PHP/Laravel 工程师。 YouTube 直播主.

归类于
Cube

Laravel 新闻通讯

加入 40,000 多名其他开发者,永不错过新提示、教程等内容。

Laravel Forge logo

Laravel Forge

轻松创建和管理您的服务器,并在几秒钟内部署您的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动完成和本地和生产环境的即时反馈进行 Tinker。

Tinkerwell
No Compromises logo

绝不妥协

Joel 和 Aaron,来自“绝不妥协”播客的两位经验丰富的开发者,现在可供您为您的 Laravel 项目聘用。⬧ 固定费率为每月 7500 美元。⬧ 没有冗长的销售流程。⬧ 没有合同。⬧ 100% 退款保证。

绝不妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,确保您的 Web 应用程序取得成功。

Kirschbaum
Shift logo

Shift

正在运行旧版本的 Laravel?立即进行自动化的 Laravel 升级和代码现代化,让您的应用程序保持新鲜。

Shift
Bacancy logo

Bacancy

只需每月 2500 美元,即可让经验丰富的 Laravel 开发人员(拥有 4-6 年经验)为您的项目增光添彩。获得 160 小时的专业技能和无风险的 15 天试用期。立即安排通话!

Bacancy
Lucky Media logo

Lucky Media

现在就来体验幸运 - 是 Laravel 开发的理想选择,拥有十多年的经验!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar:Laravel 电子商务

Laravel 的电子商务。一个开源软件包,将现代无头电子商务功能的强大功能带入 Laravel。

Lunar:Laravel 电子商务
LaraJobs logo

LaraJobs

Laravel 官方工作板

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit:Laravel SaaS 启动套件

SaaSykit 是一款 Laravel SaaS 启动套件,包含运行现代 SaaS 所需的所有功能。支付、精美结账、管理面板、用户仪表板、身份验证、即用组件、统计、博客、文档等等。

SaaSykit:Laravel SaaS 启动套件
Rector logo

Rector

您无缝升级 Laravel、降低成本并加速创新的合作伙伴,为成功企业提供助力

Rector
MongoDB logo

MongoDB

通过 MongoDB 和 Laravel 的强大集成增强您的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。支持事务性、搜索、分析和移动用例,同时使用熟悉的 Eloquent API。探索 MongoDB 灵活性、现代的数据库如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单的零依赖输入掩码库

阅读文章
Add Swagger UI to Your Laravel Application image

在您的 Laravel 应用程序中添加 Swagger UI

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel Prompts 构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的站点搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 包为您的 Laravel 应用程序添加评论

阅读文章