Добавил в сайт шифр Цезаря по роуту /caesar
This commit is contained in:
		
							parent
							
								
									36d7609b8c
								
							
						
					
					
						commit
						11c038d492
					
				| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -30,8 +30,8 @@ public function boot(): void
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->routes(function () {
 | 
					        $this->routes(function () {
 | 
				
			||||||
            Route::middleware('api')
 | 
					            Route::middleware('api')
 | 
				
			||||||
                ->prefix('api')
 | 
					                ->prefix('api/v1')
 | 
				
			||||||
                ->group(base_path('routes/api.php'));
 | 
					                ->group(base_path('routes/api_v1.php'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Route::middleware('web')
 | 
					            Route::middleware('web')
 | 
				
			||||||
                ->group(base_path('routes/web.php'));
 | 
					                ->group(base_path('routes/web.php'));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import Resume from "./views/Resume.vue";
 | 
					import Resume from "./views/resume/Resume.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
    name: "App",
 | 
					    name: "App",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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")
 | 
				
			||||||
| 
						 | 
					@ -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>
 | 
				
			||||||
| 
						 | 
					@ -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>
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,4 @@
 | 
				
			||||||
|
 | 
					|
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
 | 
					Route::get('/', 'App\Http\Controllers\Api\V1\IndexController@index')->name('caesar');
 | 
				
			||||||
    return $request->user();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					@ -18,8 +18,12 @@
 | 
				
			||||||
    return view('welcome');
 | 
					    return view('welcome');
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Route::get('/caesar', function () {
 | 
				
			||||||
 | 
					    return view('caesar/caesar');
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Route::get('/resume', function () {
 | 
					Route::get('/resume', function () {
 | 
				
			||||||
    return view('resume');
 | 
					    return view('resume/resume');
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Route::get('/download/{file}', 'App\Http\Controllers\DownloadController@download');
 | 
					Route::get('/download/{file}', 'App\Http\Controllers\DownloadController@download');
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@ export default defineConfig({
 | 
				
			||||||
    plugins: [
 | 
					    plugins: [
 | 
				
			||||||
        vue(),
 | 
					        vue(),
 | 
				
			||||||
        laravel({
 | 
					        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,
 | 
					            refresh: true,
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue