Добавил в сайт шифр Цезаря по роуту /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