Генератор случайного кода на PHP
Генерация случайной строки в программировании — популярная тема. Это связано с тем, что таким образом ресурсы можно защитить или сделать уникальными. В большинстве технологий есть готовые решения, позволяющие, например, генерировать UUID или другие типы идентификаторов. Очень полезная вещь.
Однако иногда возникает потребность в чем-то более конкретном. Я имею в виду более короткие случайные строки . Они могут действовать как, например, коды доступа, пин-коды или просто пароли.
<?php
class CodeGenerator
{
public const DEFAULT_LENGTH = 10;
public const DEFAULT_CHARACTERS = 'aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPrRsStTuUvVwWxXyYzZ0123456789';
private CodeRepository $codeRepository;
public function __construct(CodeRepository $codeRepository)
{
$this->codeRepository = $codeRepository;
}
public function generate(
int $length = self::DEFAULT_LENGTH,
string $allowedCharacters = self::DEFAULT_CHARACTERS
): string {
if ($length < 3) {
throw new \InvalidArgumentException('Code cannot be shorter than 3 chars');
}
$code = '';
$allowedCharactersLength = mb_strlen($allowedCharacters);
$codeLength = $length;
while ($codeLength !== 0) {
$randomIndex = mt_rand(0, $allowedCharactersLength - 1);
$code .= $allowedCharacters[$randomIndex];
$codeLength--;
}
if (!$this->codeRepository->isCodeUnique($code)) {
return $this->generate($length, $allowedCharacters);
}
return $code;
}
}
?>
PHP
<?php
interface CodeRepository
{
public function isCodeUnique(string $code): bool;
}
?>
PHP
<?php
class CodeGeneratorTest extends TestCase
{
public function testCannotGenerateNonUniqueCode(): void
{
$codeRepository = $this->prophesize(CodeRepository::class);
$codeRepository
->isCodeUnique(Argument::type('string'))
->willReturn(false, false, true)
->shouldBeCalledTimes(3);
$codeGenerator = new CodeGenerator($codeRepository->reveal());
$codeGenerator->generate();
}
public function testCanGenerateCodeWithDefaultLength(): void
{
$codeRepository = $this->prophesize(CodeRepository::class);
$codeRepository
->isCodeUnique(Argument::type('string'))
->willReturn(true);
$codeGenerator = new CodeGenerator($codeRepository->reveal());
$code = $codeGenerator->generate();
$this->assertEquals(CodeGenerator::DEFAULT_LENGTH, strlen($code));
}
public function testCanGenerateCodeWithOtherLengthThanDefault(): void
{
$codeRepository = $this->prophesize(CodeRepository::class);
$codeRepository
->isCodeUnique(Argument::type('string'))
->willReturn(true);
$codeGenerator = new CodeGenerator($codeRepository->reveal());
$code = $codeGenerator->generate(6);
$this->assertSame(strlen($code), 6);
}
/** @dataProvider provideWrongCodeLength */
public function testCannotGenerateCodeWithLengthLessThanThree(int $length): void
{
$codeRepository = $this->prophesize(CodeRepository::class);
$codeGenerator = new CodeGenerator($codeRepository->reveal());
$this->expectException(\InvalidArgumentException::class);
$codeGenerator->generate($length);
}
public function testCannotGenerateCodeThatContainsOtherCharsThanSpecified()
{
$codeRepository = $this->prophesize(CodeRepository::class);
$codeRepository
->isCodeUnique(Argument::type('string'))
->willReturn(true);
$codeGenerator = new CodeGenerator($codeRepository->reveal());
$allowedChars = 'aB0';
$code = $codeGenerator->generate(20, $allowedChars);
$regexChars = '/[^' . $allowedChars . ']/i';
$this->assertEquals(0, preg_match($regexChars, $code));
}
public function provideWrongCodeLength(): array
{
return [
'Length -1000' => [
'length' => -1000
],
'Length -1' => [
'length' => -1
],
'Length 0' => [
'length' => 0
],
'Length 1' => [
'length' => 1
],
'Length 2' => [
'length' => 2
]
];
}
}
?>
PHP
Вариант 2.
<?php
// Generate a Random String
function random_string( $length = 6 ) {
$conso = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
$vowels = array( "a", "e", "i", "o", "u" );
$string = "";
srand( (double)microtime()*1000000 );
for ( $i = 1; $i <= $length; $i++ ) {
$string .=$conso[rand()%strlen( $conso )];
}
return $string;
}
echo random_string( 10 );
?>
PHP
Генераторы
ПрограммированиеPHP