Skip to content

Commit 3e85e23

Browse files
committed
Added Base 16 encoded implementation.
1 parent b870297 commit 3e85e23

File tree

3 files changed

+515
-47
lines changed

3 files changed

+515
-47
lines changed

source/Jocic/Encoders/Base/Base16.php

Lines changed: 362 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
<?php
2+
3+
/*******************************************************************\
4+
|* Author: Djordje Jocic *|
5+
|* Year: 2019 *|
6+
|* License: MIT License (MIT) *|
7+
|* =============================================================== *|
8+
|* Personal Website: http://www.djordjejocic.com/ *|
9+
|* =============================================================== *|
10+
|* Permission is hereby granted, free of charge, to any person *|
11+
|* obtaining a copy of this software and associated documentation *|
12+
|* files (the "Software"), to deal in the Software without *|
13+
|* restriction, including without limitation the rights to use, *|
14+
|* copy, modify, merge, publish, distribute, sublicense, and/or *|
15+
|* sell copies of the Software, and to permit persons to whom the *|
16+
|* Software is furnished to do so, subject to the following *|
17+
|* conditions. *|
18+
|* --------------------------------------------------------------- *|
19+
|* The above copyright notice and this permission notice shall be *|
20+
|* included in all copies or substantial portions of the Software. *|
21+
|* --------------------------------------------------------------- *|
22+
|* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *|
23+
|* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *|
24+
|* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *|
25+
|* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *|
26+
|* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, *|
27+
|* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, RISING *|
28+
|* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *|
29+
|* OTHER DEALINGS IN THE SOFTWARE. *|
30+
\*******************************************************************/
31+
32+
namespace Jocic\Encoders\Base;
33+
34+
use Jocic\Encoders\DefaultInterface;
35+
36+
/**
37+
* <i>Base16</i> class is used for encoding data in <i>Base 16</i> format.
38+
*
39+
* @author Djordje Jocic <[email protected]>
40+
* @copyright 2019 All Rights Reserved
41+
* @version 1.0.0
42+
*/
43+
44+
class Base16 extends BaseCore implements DefaultInterface, BaseInterface
45+
{
46+
/******************\
47+
|* CORE CONSTANTS *|
48+
\******************/
49+
50+
// CORE CONSTANTS GO HERE
51+
52+
/******************\
53+
|* CORE VARIABLES *|
54+
\******************/
55+
56+
/**
57+
* Array containing characters of the encoding table for <i>Base 16</i>
58+
* encoding per <i>RFC 4648</i> specifications.
59+
*
60+
* Note: Review page 10 of the mentioned document for more information.
61+
*
62+
* @var array
63+
* @access private
64+
*/
65+
66+
private $baseTable = [
67+
"0", "1", "2", "3", "4", "5", "6", "7",
68+
"8", "9", "A", "B", "C", "D", "E", "F"
69+
];
70+
71+
/*******************\
72+
|* MAGIC FUNCTIONS *|
73+
\*******************/
74+
75+
// MAGIC FUNCTIONS GO HERE
76+
77+
/***************\
78+
|* GET METHODS *|
79+
\***************/
80+
81+
/**
82+
* Returns an array containing characters of the encoding table for
83+
* <i>Base 16</i> encoding per <i>RFC 4648</i> specifications.
84+
*
85+
* @author Djordje Jocic <[email protected]>
86+
* @copyright 2019 All Rights Reserved
87+
* @version 1.0.0
88+
*
89+
* @return array
90+
* Array containing characters of the encoding table.
91+
*/
92+
93+
public function getBaseTable()
94+
{
95+
// Logic
96+
97+
return $this->baseTable;
98+
}
99+
100+
/**
101+
* Returns an empty string as <i>Base 16</i> encoding isn't padded.
102+
*
103+
* @author Djordje Jocic <[email protected]>
104+
* @copyright 2019 All Rights Reserved
105+
* @version 1.0.0
106+
*
107+
* @return string
108+
* String containing a single character used for padding-purposes.
109+
*/
110+
111+
public function getBasePadding()
112+
{
113+
// Logic
114+
115+
return "";
116+
}
117+
118+
/***************\
119+
|* SET METHODS *|
120+
\***************/
121+
122+
// SET METHODS GO HERE
123+
124+
/****************\
125+
|* CORE METHODS *|
126+
\****************/
127+
128+
/**
129+
* Encodes a provided string to <i>Base 16</i> encoding.
130+
*
131+
* @author Djordje Jocic <[email protected]>
132+
* @copyright 2019 All Rights Reserved
133+
* @version 1.0.0
134+
*
135+
* @param string $input
136+
* Input string that needs to be encoded.
137+
* @return string
138+
* Encoded input per used specifications.
139+
*/
140+
141+
public function encode($input)
142+
{
143+
// Core Variables
144+
145+
$baseTable = $this->getBaseTable();
146+
$output = "";
147+
$chunks = [];
148+
149+
// Step 1 - Handle Empty Input
150+
151+
if ($input == "")
152+
{
153+
return "";
154+
}
155+
156+
// Step 2 - Split Input Into 4-bit Chunks
157+
158+
$chunks = $this->convertInputToChunks($input);
159+
160+
// Step 3 - Process Chunks
161+
162+
foreach ($chunks as $chunk)
163+
{
164+
$output .= $baseTable[$chunk];
165+
}
166+
167+
// Step 4 - Apply Padding & Return Encoding
168+
169+
return $output;
170+
}
171+
172+
/**
173+
* Decodes a provided string from <i>Base 16</i> encoding.
174+
*
175+
* @author Djordje Jocic <[email protected]>
176+
* @copyright 2019 All Rights Reserved
177+
* @version 1.0.0
178+
*
179+
* @param string $input
180+
* Input string that needs to be decoded.
181+
* @return string
182+
* Decoded input per used specifications.
183+
*/
184+
185+
public function decode($input)
186+
{
187+
// Core Variables
188+
189+
$chunks = [];
190+
191+
// Step 1 - Handle Empty Input
192+
193+
if ($input == "")
194+
{
195+
return "";
196+
}
197+
198+
// Step 2 - Decode Input Into 4-bit Chunks
199+
200+
$chunks = $this->convertEncodingToChunks($input);
201+
202+
// Step 3 - Merge Dervided Chunks
203+
204+
$input = $this->mergeEncodingChunks($chunks);
205+
206+
// Step 4 - Return Decoding
207+
208+
return $input;
209+
}
210+
211+
/*****************\
212+
|* CHECK METHODS *|
213+
\*****************/
214+
215+
/**
216+
* Checks if the <i>Base 16</i> encoding is valid or not.
217+
*
218+
* Note: Invalid encodings should be rejected per section <i>3.3</i>
219+
* in the <i>RFC 4648</i> specifications.
220+
*
221+
* @author Djordje Jocic <[email protected]>
222+
* @copyright 2019 All Rights Reserved
223+
* @version 1.0.0
224+
*
225+
* @param string $encoding
226+
* <i>Base 16</i> encoding that needs to be checked.
227+
* @return bool
228+
* Value <i>True</i> if encoding is valid, and vice versa.
229+
*/
230+
231+
public function isEncodingValid($encoding)
232+
{
233+
// Core Variables
234+
235+
$baseTable = $this->getBaseTable();
236+
237+
// Other Variables
238+
239+
$characters = [];
240+
241+
// Step 1 - Check If Empty
242+
243+
if ($encoding == "")
244+
{
245+
return true;
246+
}
247+
248+
// Step 2 - Check General Form
249+
250+
if (!preg_match("/^([A-z0-9]+)?$/", $encoding))
251+
{
252+
return false;
253+
}
254+
255+
// Step 3 - Generate Character Array
256+
257+
$characters = str_split($encoding);
258+
259+
// Step 4 - Check Characters
260+
261+
foreach ($characters as $character)
262+
{
263+
if (!in_array($character, $baseTable))
264+
{
265+
return false;
266+
}
267+
}
268+
269+
return true;
270+
}
271+
272+
/********************\
273+
|* ENCODING METHODS *|
274+
\********************/
275+
276+
/**
277+
* Converts provided string into chunks - 4-bit values.
278+
*
279+
* @author Djordje Jocic <[email protected]>
280+
* @copyright 2019 All Rights Reserved
281+
* @version 1.0.0
282+
*
283+
* @param string $input
284+
* Input that needs to be converted to chunks.
285+
* @return array
286+
* Array containing chunks (4-bit values).
287+
*/
288+
289+
public function convertInputToChunks($input)
290+
{
291+
// Core Variables
292+
293+
$characters = null;
294+
295+
// Chunk Variables
296+
297+
$chunks = [];
298+
$byte = null;
299+
300+
// Logic
301+
302+
$characters = str_split($input);
303+
304+
foreach ($characters as $character)
305+
{
306+
// Convert Character To Byte
307+
308+
$byte = ord($character) & 0xFF;
309+
310+
// Split Byte Into Chunks
311+
312+
$chunks[] = ($byte & 0xF0) >> 4;
313+
$chunks[] = ($byte & 0x0F) >> 0;
314+
}
315+
316+
return $chunks;
317+
}
318+
319+
/********************\
320+
|* DECODING METHODS *|
321+
\********************/
322+
323+
/**
324+
* Merges encoding chunks into a single string.
325+
*
326+
* @author Djordje Jocic <[email protected]>
327+
* @copyright 2019 All Rights Reserved
328+
* @version 1.0.0
329+
*
330+
* @param array $chunks
331+
* Encoding chunks that should be merged.
332+
* @return string
333+
* Merged encoding chunks - actual decoding.
334+
*/
335+
336+
public function mergeEncodingChunks($chunks)
337+
{
338+
// Core Variables
339+
340+
$decoding = "";
341+
$byte = null;
342+
343+
// Logic
344+
345+
for ($i = 0; $i < count($chunks); $i += 2)
346+
{
347+
$byte = (($chunks[$i] << 4) | $chunks[$i + 1]) & 0xFF;
348+
349+
$decoding .= sprintf("%c", $byte);
350+
}
351+
352+
return $decoding;
353+
}
354+
355+
/*****************\
356+
|* OTHER METHODS *|
357+
\*****************/
358+
359+
// OTHER METHODS GO HERE
360+
}
361+
362+
?>

0 commit comments

Comments
 (0)