You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
114 lines
3.1 KiB
PHP
114 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\ImageCaptcha;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
use Yo;
|
|
|
|
class ImageCaptchaController extends Controller
|
|
{
|
|
public function check($hash, $code, $time, $uuid)
|
|
{
|
|
$code = mb_strtoupper($code);
|
|
$captcha = ImageCaptcha::where('uuid', $uuid)->first();
|
|
if ($captcha) return 100005;
|
|
if (time() - $time > 60 * 3) return 100005;
|
|
if (Hash::check($code . ',Captcha,' . $uuid . ',' . $time, $hash)) {
|
|
$captcha = new ImageCaptcha();
|
|
$captcha->uuid = $uuid;
|
|
$captcha->save();
|
|
return 0;
|
|
} else {
|
|
return 100006;
|
|
}
|
|
}
|
|
|
|
public function create()
|
|
{
|
|
$captcha = $this->generateCaptcha();
|
|
$imageBase64 = $this->getImageBase64($captcha['image']);
|
|
$time = time();
|
|
$uuid = Str::orderedUuid();
|
|
$code = mb_strtoupper($captcha['code']);
|
|
$hash = Hash::make($code . ',Captcha,' . $uuid . ',' . $time);
|
|
$ret = [
|
|
'image' => $imageBase64,
|
|
'hash' => $hash,
|
|
'time' => $time,
|
|
'uuid' => $uuid,
|
|
];
|
|
if (app()->isLocal()) {
|
|
$ret['code'] = $code;
|
|
$ret['account'] = 'admin';
|
|
$ret['password'] = '000000';
|
|
}
|
|
return Yo::echo($ret);
|
|
}
|
|
|
|
private function generateCaptcha()
|
|
{
|
|
$code = $this->generateRandomCode();
|
|
$image = $this->generateImage($code);
|
|
return [
|
|
'code' => $code,
|
|
'image' => $image
|
|
];
|
|
}
|
|
|
|
private function generateRandomCode()
|
|
{
|
|
$code = '';
|
|
$characters = '34acdefhkmnprstwxyACDEFGHKMNPQRWXY';
|
|
for ($i = 0; $i < 6; $i++) {
|
|
$code .= $characters[rand(0, strlen($characters) - 1)];
|
|
}
|
|
return $code;
|
|
}
|
|
|
|
private function generateImage($code)
|
|
{
|
|
$draw_width = 120;
|
|
$draw_height = 40;
|
|
$image = imagecreate($draw_width, $draw_height);
|
|
imagecolorallocate($image, 255, 255, 255);
|
|
for ($i = 0; $i < 100; $i++) {
|
|
$x = rand(0, 120);
|
|
$y = rand(0, 40);
|
|
$color = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
|
|
imagesetpixel($image, $x, $y, $color);
|
|
}
|
|
for ($i = 0; $i < 5; $i++) {
|
|
$x1 = rand(0, 120);
|
|
$y1 = rand(0, 40);
|
|
$x2 = rand(0, 120);
|
|
$y2 = rand(0, 40);
|
|
$color = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
|
|
imageline($image, $x1, $y1, $x2, $y2, $color);
|
|
}
|
|
$font_file = 'assets/captcha.ttf';
|
|
$original_path = Storage::disk('public')->path($font_file);
|
|
$code_size = 26;
|
|
for ($i = 0; $i < mb_strlen($code); $i++) {
|
|
$c = mb_substr($code, $i, 1);
|
|
$r = rand(-20, 20);
|
|
$c_box = imagettfbbox($code_size, $r, $original_path, $c);
|
|
imagettftext($image, $code_size, $r, 2 + ceil((18 - $c_box[2]) / 2) + (18 * $i), ceil(($draw_height - $c_box[5]) / 2),
|
|
imagecolorallocate($image, rand(0, 200), rand(0, 200), rand(0, 200)), $original_path, $c);
|
|
}
|
|
ob_start();
|
|
imagepng($image);
|
|
$imageData = ob_get_clean();
|
|
return $imageData;
|
|
}
|
|
|
|
private function getImageBase64($imageData)
|
|
{
|
|
$imageBase64 = base64_encode($imageData);
|
|
return 'data:image/png;base64,' . $imageBase64;
|
|
}
|
|
}
|