Добавил в сайт шифр Цезаря по роуту /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 () { | ||||
|             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')); | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ | |||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| import Resume from "./views/Resume.vue"; | ||||
| import Resume from "./views/resume/Resume.vue"; | ||||
| 
 | ||||
| export default { | ||||
|     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) { | ||||
|     return $request->user(); | ||||
| }); | ||||
| Route::get('/', 'App\Http\Controllers\Api\V1\IndexController@index')->name('caesar'); | ||||
|  | @ -18,8 +18,12 @@ | |||
|     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'); | ||||
|  |  | |||
|  | @ -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, | ||||
|         }), | ||||
|     ], | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue