Skip to content

Commit 421e44a

Browse files
committed
[DEV] Add Vigenere Abstract;
1 parent 5df03ae commit 421e44a

File tree

1 file changed

+222
-0
lines changed

1 file changed

+222
-0
lines changed

source/VigenereCipherBlueprint.php

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
<?php
2+
namespace amculin\cryptography\classic;
3+
4+
use amculin\cryptography\classic\enums\ProcessType;
5+
6+
abstract class VigenereCipherBlueprint
7+
{
8+
/**
9+
* Default list of acceptable character to be used in vigenere cipher algorithm
10+
* By default, it just an alphabetical list.
11+
*
12+
* @var string
13+
*/
14+
public $tabulaRecta;
15+
16+
/**
17+
* The current process whether it is encrypt or decrypt
18+
*
19+
* @var string
20+
*/
21+
public $process;
22+
23+
/**
24+
* The plain text/message to be encrypted
25+
*
26+
* @var string
27+
*/
28+
public $plainText;
29+
30+
/**
31+
* The key used to encrypt plain text/message
32+
*
33+
* @var string
34+
*/
35+
public $key;
36+
37+
/**
38+
* The cipher text to be decrypted
39+
*
40+
* @var string
41+
*/
42+
public $cipherText;
43+
44+
public function __construct(string $process = 'encrypt', string $data = null, string $key = null)
45+
{
46+
$this->setProcess($process);
47+
48+
if ($process == ProcessType::ENCRYPT->value) {
49+
if (! is_null($data) && ! is_null($key)) {
50+
$this->setPlainText($data);
51+
$this->setKey($key);
52+
$this->encrypt();
53+
}
54+
} else {
55+
if (! is_null($data) && ! is_null($key)) {
56+
$this->setCipherText($data);
57+
$this->setKey($key);
58+
$this->decrypt();
59+
}
60+
}
61+
}
62+
63+
/**
64+
* Method to get current process
65+
*
66+
* @return string
67+
*/
68+
public function getProcess(): string
69+
{
70+
return $this->process;
71+
}
72+
73+
/**
74+
* Set the current process
75+
*
76+
* @param string process
77+
* @return void
78+
*/
79+
public function setProcess(string $process): void
80+
{
81+
$this->process = $process;
82+
}
83+
84+
/**
85+
* Method to get plain text
86+
*
87+
* @return string
88+
*/
89+
public function getPlainText(): string
90+
{
91+
return $this->plainText;
92+
}
93+
94+
/**
95+
* Set the plain text/message/data to be encrypted
96+
*
97+
* @param string message
98+
* @return void
99+
*/
100+
public function setPlainText(string $plainText): void
101+
{
102+
$this->plainText = $plainText;
103+
}
104+
105+
/**
106+
* Method to get key
107+
*
108+
* @return string
109+
*/
110+
public function getKey(): string
111+
{
112+
return $this->key;
113+
}
114+
115+
/**
116+
* Set the key to be be used in encryption/decryption process
117+
*
118+
* @param string key
119+
* @return void
120+
*/
121+
public function setKey(string $key): void
122+
{
123+
$paddedKey = $this->generateKey($key);
124+
125+
$this->key = $paddedKey;
126+
}
127+
128+
/**
129+
* Method to get cipher text
130+
*
131+
* @return string
132+
*/
133+
public function getCipherText(): string
134+
{
135+
return $this->cipherText;
136+
}
137+
138+
/**
139+
* Set the cipher text result from encryption process
140+
*
141+
* @param string message
142+
* @return void
143+
*/
144+
public function setCipherText(string $cipherText): void
145+
{
146+
$this->cipherText = $cipherText;
147+
}
148+
149+
/**
150+
* Method to generate the key
151+
* We loop the key then concatenate it until it has the same length with the plain text
152+
* Example:
153+
* Plain text: vigenerecipher (14 characters)
154+
* Key: abcd (4 characters)
155+
* Repeated key: abcdabcdabcdab (14 characters)
156+
*
157+
* @param string key
158+
* @return string
159+
*/
160+
public function generateKey(string $key): string
161+
{
162+
$keyLength = strlen($key);
163+
$messageLength = strlen($this->process == ProcessType::ENCRYPT->value ? $this->plainText :
164+
$this->cipherText);
165+
166+
$repeatTimes = floor($messageLength / $keyLength);
167+
$paddingKeyLength = $messageLength - ($keyLength * $repeatTimes);
168+
169+
$repeatedKey = '';
170+
171+
for ($i = 0; $i < $repeatTimes; $i++) {
172+
$repeatedKey .= $key;
173+
}
174+
175+
return $repeatedKey . substr($key, 0, $paddingKeyLength);
176+
}
177+
178+
/**
179+
* Method to encrypt the plain text
180+
*
181+
* @return void
182+
*/
183+
public function encrypt(): void
184+
{
185+
$messageLength = strlen($this->plainText);
186+
$cipher = '';
187+
188+
for ($i = 0; $i < $messageLength; $i++) {
189+
$messageCharPosition = strpos($this->tabulaRecta, substr($this->plainText, $i, 1));
190+
$keyCharPosition = strpos($this->tabulaRecta, substr($this->key, $i, 1));
191+
192+
$shift = $messageCharPosition + $keyCharPosition;
193+
$cipherCharPosition = $shift % strlen($this->tabulaRecta);
194+
$cipher .= substr($this->tabulaRecta, $cipherCharPosition, 1);
195+
}
196+
197+
$this->setCipherText($cipher);
198+
}
199+
200+
/**
201+
* Method to decrypt the cipher text
202+
*
203+
* @return void
204+
*/
205+
public function decrypt(): void
206+
{
207+
$messageLength = strlen($this->cipherText);
208+
$plain = '';
209+
210+
for ($i = 0; $i < $messageLength; $i++) {
211+
$messageCharPosition = strpos($this->tabulaRecta, substr($this->cipherText, $i, 1));
212+
$keyCharPosition = strpos($this->tabulaRecta, substr($this->key, $i, 1));
213+
214+
$shift = $messageCharPosition - $keyCharPosition;
215+
$plainCharPosition = $shift % strlen($this->tabulaRecta);
216+
217+
$plain .= substr($this->tabulaRecta, $plainCharPosition, 1);
218+
}
219+
220+
$this->setPlainText($plain);
221+
}
222+
}

0 commit comments

Comments
 (0)