Решил на днях еще немного добавить статей на свой сайт, и немного подумав чем полезным мне можно поделиться, вспомнил о недавно созданной функции для шифрования кода в php с помощью base64. В php использование base64 осуществляеться функциями base64_encode и base64_decode. Соответвенно преобразование и обратное декодирование. Алгоритм base64 удобен тем, что закодированые данные можно отправлять GET запросом без предварительного urlencode. И кодировать можно абсолютно все, любые бинарные данные, такие как рисунки, exe-файлы, dll библиотеки и т.д. И весь закодированые код превращается текстовую строку удобную для передачи через HTTP запросы или хранения в базах данных.
Так вот, если с кодированием и декодированием проблем нет, это делают уже упоминаемые выше функции base64_encode и base64_decode. То вот закодировать эти данные со специальным ключем, без которого никто не сможет декодировать не предусмотрено. Другими словами, любой может декодировать ваш код и получить исходные данные.
Передо мной недавно встала подобная задача и я немного подумав решил ее таким способом. После кодирования данных мы получаем текстовую строку с предусмотренными символами:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
например, закодируем следующую строку текста: "hello world, it‘s a source data"
и получим:
aGVsbG8gd29ybGQsIGl0J3MgYSBzb3VyY2UgZGF0YQ==
Но, этот код может расшифровать кто угодно и узнать наш исходный текст.
Я подумал почему бы не разбить закодированную строку по десяткам символам, в каждой десятке поменять позиции всех символов согласно определенному правилу. Этим мы достигнем двух целей:
1. не изменяться типы символом, фактически строка будет состоять из тех же символов, но в другом порядке
2. размер строки тоже не измениться
3. вероятность того, что кто-то сможет расшифровать довольно низка, при необходимости можно делить строку не на десятки, а на любое количество символов и внутри каждой групы менять позицию символов
4. прочитать исходные данные невозможно даже частично, то и есть никаких кусков текста в виде слов никто не увидит
На основе своей идеи я создал скрипт:
Example encoding text row with base64 where result is sequence of primary encoded row and each tenner has changed position each symbol <br><br>
Example text:
<div
style="color: blue">
<?php
echo $text = "hello world, it's a source data"; ?>
</div>
<br>
Example ordinary code base64:
<div
style="color: blue">
<?php
echo base64_encode($text); ?>
</div>
<br>
Example code base64 with encrypting:
<div
style="color: blue">
<?php
echo $code = _base64($text,'encode',true); ?>
</div>
<br>
Example decoded base64 with encrypting ordinary function base64_decode:
<div
style="color: blue">
<?php
echo base64_decode($code); ?>
</div>
<br>
Example decode base64 with encrypting:
<div
style="color: blue">
<?php
echo _base64($code,'decode',true); ?>
</div>
<?php
/*
*
* This function encodes/decodes text according base64 algorithm.
* Besides function uses encrypting for defend encoded row.
*
* @param string $string Text or encripted row
* @param string $mode encode/decode
* @param boolean $encrypting Use encrypting or not
*
* @return string Encoded row with encrypting/non-encrypting or decoded text
*
* Example
*
* $text = "hello world";
* $code = _base64($text,'encode',true);
* $text = _base64($code,'decode',true);
*
*
*
*
*/
function _base64($string, $mode = 'encode', $encrypting = false){
if (empty($string)) return false;
if (empty($encrypting)){
switch ($mode) {
case 'encode': return base64_encode($string);
case 'decode': return base64_decode($string);
default: return false;
}
}
if ($mode == 'encode') $string = base64_encode($string);
/* Rule of encryption
* combination of rules
* from 0 - 9 each item must be unique,
*
* array where:
* key is number position
* value is number a symbol from tenner
*/
$rule = array(1,6,8,4,0,5,9,7,2,3);
/*
* creation array where each item has
* sequence of current code (tenner)
*/
$y = $z = 0;
for($x = 0;$x <
strlen($string); $x++){
if ($x % (count($rule)) == 0){
if ($x > 0) {
$y++;
$z = 0;
}
}
$aSequence[$y][$z++] = substr($string, $x, 1);
}
$aResult = array();
switch ($mode) {
case 'encode':
/*
* encode current string by rule
*/
foreach($aSequence as $row){
foreach($rule as $val){
$aResult[] = isset($row[$val]) ? $row[$val] : '-';
}
}
break;
case 'decode':
/*
* decode current string by rule
*/
$rule = array_flip($rule);
ksort($rule);
foreach($aSequence as $row){
foreach($rule as $val){
$aResult[] = (isset($row[$val]) && $row[$val] != '-') ? $row[$val] : '';
}
}
return _base64(implode('',$aResult), 'decode');
default: return false;
}
return implode('',$aResult);
}
?>
Сохраните этот кусок кода в php файл и выполните его. В результате выполнения будет выведено следующее:
Example encoding text row with base64 where result is sequence of primary encoded row and each tenner has changed position each symbol
Example text:
hello world, it's a source data
Example ordinary code base64:
aGVsbG8gd29ybGQsIGl0J3MgYSBzb3VyY2UgZGF0YQ==
Example code base64 with encrypting:
G8dbaG2gVsyIlQ9s0GbG3BbYJS3zMgyZFUVg0GY2Q---Y---==
Example decoded base64 with encrypting ordinary function base64_decode:
«[hm†VћИХl–f∆№Ў%-у2ЩE`–f6A
Example decode base64 with encrypting:
hello world, it's a source data
Как видите, если декодировать код стандартными средствами php, получится нечитаемый набор символов.
Практическое применение этой возможности может быть полезно для данных, которые могут храниться на стороне клиента. Или, например, можно создать удаленный сервис, который будет расшифровывать закодированый код, а сам код пользователи будут получать в результате оплаты товаров или еще чего-то такого. Вообщем, если Вам нужно было, то пользуйтесь ;)