Добавил в сайт шифр Цезаря по роуту /caesar

This commit is contained in:
p.belezov 2024-01-23 17:55:28 +08:00
parent 36d7609b8c
commit 11c038d492
11 changed files with 308 additions and 8 deletions

View File

@ -0,0 +1,127 @@
<?php
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
class IndexController extends Controller
{
public function index()
{
$cd = intval($_GET["cd"]);
$text = str($_GET["text"]);
$shift = intval($_GET["shift"]);
$language = str($_GET["language"]);
$shift = $this->normalizeShift($shift, $language);
$result_text = '';
if ($language == 'Ru'){
if ($cd == 0){
$result_text = $this->ruEncipher($text, $shift);
} elseif ($cd == 1){
$result_text = $this->ruDecipher($text, $shift);
}
} elseif ($language == 'En') {
if ($cd == 0){
$result_text = $this->enEncipher($text, $shift);
} elseif ($cd == 1){
$result_text = $this->enDecipher($text, $shift);
}
}
return $result_text;
}
public function normalizeShift($shift, $alphabet)
{
if ($alphabet == 'Ru'){
if ($shift > 32){
while ($shift > 32)
{
$shift = $shift - 32;
}
}
return $shift;
} elseif ($alphabet == 'En') {
if ($shift > 26){
while ($shift > 26)
{
$shift = $shift - 26;
}
}
return $shift;
}
}
public function enCipher($ch, $key)
{
if (!ctype_alpha($ch))
return $ch;
$offset = ord(ctype_upper($ch) ? 'A' : 'a');
return chr(fmod(((ord($ch) + $key) - $offset), 26) + $offset);
}
public function enEncipher($input, $key)
{
$output = "";
$inputArr = str_split($input);
foreach ($inputArr as $ch)
$output .= $this->enCipher($ch, $key);
return $output;
}
public function enDecipher($input, $key)
{
return $this->enEncipher($input, 26 - $key);
}
public function ruCipher($ch, $key)
{
$regexp = "/[А-ЯЁа-яё]/";
$regexp_upper = "/[А-ЯЁ]\{Lu}/";
if (!preg_match($regexp, $ch))
{
return $ch;
}
$offset = mb_ord(preg_match($regexp_upper, $ch) ? 'А' : 'а', "UTF-8");
return mb_chr(fmod(((mb_ord($ch, "UTF-8") + $key) - $offset), 32) + $offset, "UTF-8");
}
function ruCipherReverse($ch, $key)
{
$regexp = "/[А-ЯЁа-яё]/";
$regexp_upper = "/[А-ЯЁ]\{Lu}/";
if (!preg_match($regexp, $ch))
{
return $ch;
}
$offset = mb_ord(preg_match($regexp_upper, $ch) ? 'А' : 'а', "UTF-8");
return mb_chr(fmod(((mb_ord($ch, "UTF-8") - $key) - $offset), 32) + $offset, "UTF-8");
}
public function ruEncipher($input, $key)
{
$output = "";
$inputArr = mb_str_split($input, 1, "UTF-8");
foreach ($inputArr as $ch)
$output .= $this->ruCipher($ch, $key);
return $output;
}
public function ruDecipher($input, $key)
{
$output = "";
$inputArr = mb_str_split($input, 1, "UTF-8");
foreach ($inputArr as $ch)
$output .= $this->ruCipherReverse($ch, $key);
return $output;
}
}

View File

@ -30,8 +30,8 @@ class RouteServiceProvider extends ServiceProvider
$this->routes(function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
->prefix('api/v1')
->group(base_path('routes/api_v1.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));

View File

@ -5,7 +5,7 @@
</template>
<script>
import Resume from "./views/Resume.vue";
import Resume from "./views/resume/Resume.vue";
export default {
name: "App",

16
resources/caesar.js Normal file
View File

@ -0,0 +1,16 @@
import './js/bootstrap';
import {createApp} from 'vue'
import App from './views/caesar/Caesar.vue'
import { createVuetify } from 'vuetify'
import { mdi } from "vuetify/iconsets/mdi";
import 'vuetify/styles'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import '@mdi/font/css/materialdesignicons.css'
const vuetify = createVuetify({
components,
directives
})
createApp(App).use(vuetify).mount("#app")

View File

@ -0,0 +1,142 @@
<template>
<v-app>
<v-card class="bg-gradient h-100" style="height: 100%">
<v-card-text class="d-flex justify-center align-center">
<v-card title="Code" id="code-form" class="align-center justify-center h-auto w-33">
<v-card-text>
<v-text-field id="code-text" label="Text" variant="outlined" :rules="rules" v-model="codeText"></v-text-field>
<v-text-field id="code-shift" label="Shift" variant="outlined" :rules="rulesNum" v-model="codeShift"></v-text-field>
<v-switch
v-model="codeLang"
color="primary"
hide-details
true-value="Ru"
false-value="En"
:label="`Language: ${codeLang}`"
></v-switch>
<v-text-field loading id="code-result" label="Result" variant="outlined" v-model="codeOutput">
<template v-slot:loader>
<v-progress-linear
:active="isLoadingCode"
color="warning"
height="3"
indeterminate
></v-progress-linear>
</template>
</v-text-field>
<div style="text-align: center"><v-btn @click="caesarCipher(0)" class="customBtn">Code</v-btn></div>
</v-card-text>
<!--<v-card-actions><v-btn>Code</v-btn></v-card-actions>-->
</v-card>
<v-card title="Decode" id="decode-form" class="align-center justify-center h-auto w-33">
<v-card-text>
<v-text-field id="decode-text" label="Text" variant="outlined" :rules="rules" v-model="decodeText"></v-text-field>
<v-text-field id="decode-shift" label="Shift" variant="outlined" :rules="rulesNum" v-model="decodeShift"></v-text-field>
<v-switch
v-model="decodeLang"
color="primary"
hide-details
true-value="Ru"
false-value="En"
:label="`Language: ${decodeLang}`"
></v-switch>
<v-text-field id="decode-result" label="Result" variant="outlined" v-model="decodeOutput">
<template v-slot:loader>
<v-progress-linear
:active="isLoadingDecode"
color="warning"
height="3"
indeterminate
></v-progress-linear>
</template>
</v-text-field>
<div style="text-align: center"><v-btn @click="caesarCipher(1)" class="customBtn">Decode</v-btn></div>
</v-card-text>
</v-card>
</v-card-text>
</v-card>
</v-app>
</template>
<script>
import axios from 'axios';
export default {
name: "Caesar",
data: () => ({
rules: [
value => !!value || 'Required.',
],
rulesNum: [
value => !!value || 'Required.',
value => /^\d+$/.test(value) || 'Digits only',
value => parseInt(value) >= 0 || 'Shift must be > 0'
],
codeOutput: '',
decodeOutput: '',
codeText: '',
codeShift: 0,
decodeText: '',
decodeShift: 0,
codeLang: 'En',
decodeLang: 'En',
isLoadingCode: false,
isLoadingDecode: false
}),
methods: {
caesarCipher(cd){
async function getResp (cdNum, text, shift, language){
let resp = await axios.get('/api/v1', { params: { cd: cdNum, text: text, shift: shift, language: language } });
return resp.data;
}
if (cd === 0){
this.isLoadingCode = true;
this.codeOutput = '';
getResp(cd, this.codeText, this.codeShift, this.codeLang).then( (res) => {
this.codeOutput = res;
this.isLoadingCode = false;
});
} else if (cd === 1){
this.isLoadingDecode = true;
this.decodeOutput = '';
getResp(cd, this.decodeText, this.decodeShift, this.decodeLang).then((res) => {
this.decodeOutput = res;
this.isLoadingDecode = false;
});
}
},
}
}
</script>
<style scoped>
.bg-gradient {
background: linear-gradient(-45deg, #6947ea, #ffd298, #4698bb);
background-size: 200% 200%;
animation: gradient 15s ease infinite;
height: 100vh;
}
@keyframes gradient {
0% {
background-position: 0 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0 50%;
}
}
.customBtn {
background-color: #0d47a1;
color: mintcream;
}
#code-form {
margin-right: 2em;
}
</style>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Caesar</title>
@vite('resources/caesar.js')
@vite('resources/css/app.css')
</head>
<body>
<div id="app"></div>
</body>
</html>

View File

@ -14,6 +14,4 @@ use Illuminate\Support\Facades\Route;
|
*/
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::get('/', 'App\Http\Controllers\Api\V1\IndexController@index')->name('caesar');

View File

@ -18,8 +18,12 @@ Route::get('/', function () {
return view('welcome');
});
Route::get('/caesar', function () {
return view('caesar/caesar');
});
Route::get('/resume', function () {
return view('resume');
return view('resume/resume');
});
Route::get('/download/{file}', 'App\Http\Controllers\DownloadController@download');

View File

@ -6,7 +6,7 @@ export default defineConfig({
plugins: [
vue(),
laravel({
input: ['resources/css/app.css', 'resources/app.js', 'resources/welcome.js'],
input: ['resources/css/app.css', 'resources/app.js', 'resources/welcome.js', 'resources/caesar.js'],
refresh: true,
}),
],