Шифруем файлы в черно-белых изображениях.

Шифруем файлы в черно-белых изображениях.

@Garant_Copy

Привет, %user%! Одним скучным вечером захотелось мне что-то накодить. Шифратор текста — первое, что пришло мне в голову. Но когда он был готов, оказалось, что он может шифровать любые файлы! В данном примере есть ограничение на размер файла. Файлы весом более 200 кб ему скармливать не следует. Писать сам скрипт будем на PHP.



Идея


Шифруем: читаем содержимое файла, преобразуем его в 0 и 1, цифры преобразуем в пиксели и записываем в файл.

Расшифровываем: читаем файл, определяем цвет каждого пикселя, получаем 0 и 1, из них получаем текст и записываем его в файл.


Приступим!


Для начала, напишем несколько служебных функций:

function readln(){
    $stdin = fopen('php://stdin', 'r'); 
    return trim(fread($stdin, 2048));
}

function ascii_decrypt($encryptedtext)
{
    $encryptedtext = str_replace(' ', '', $encryptedtext);
    $encryptedtext = str_replace("\n", '', $encryptedtext);
    $encryptedtext = str_replace("\r", '', $encryptedtext);

    $blockstack = str_split($encryptedtext, 8);
    $plaintext = "";
    while(list($key, $val) = each($blockstack))
    {
        $plaintext .= bin2ascii($val);
    }
    return $plaintext;
}

function ascii_encrypt($plaintext)
{
    $plaintextlength = strlen($plaintext);
    $i=0;
    for($x = 0; $x < $plaintextlength; $x++)
    {
        $pt .= ascii2bin($plaintext[$x]);
        //$encryptedtext .= " ";
    }
    return $pt;
}

function ascii2bin($char)
{
    $char = decbin(ord($char));
    $char = str_pad($char, 8, '0', STR_PAD_LEFT);
    return $char;
}

function bin2ascii($binary)
{
    $char = substr($binary, $x, 8);
    $char = chr(bindec($char));
    return $char;
}



Поясню.

Функция readln() читает вводимый текст из командной строки. ascii_encrypt() переводит текст в 0 и 1, а ascii_decrypt() выполняет обратное действие. ascii2bin()преобразует символ в последовательность из 8-ми ноликов и единичек, а bin2ascii(), естественно, выполняет обратное действие.


Теперь главное — шифруем и расшифровываем. Пояснять не буду, так как код и так хорошо прокомментирован.


Шифруем


echo "Input file: ";
$fl = readln($fl);

if(file_exists($fl)) $file = stripslashes(file_get_contents($fl)); else die("Input file not found!\n");
//header('Content-Type: image/png');

//Содержимое файла преобразуем в нолики и единицы... 
//И зачем-то переворачиваем)
$e = strrev(ascii_encrypt($file));

////Нехитрый код для вычисления высоты и ширины рисунка
$l = strlen($e);
$h = floor(sqrt($l));
while($l%$h !== 0) $h--;
$w = $l/$h;
//Разбиваем всю кашу по одному символу
$wordDot = str_split($e, 1);

$line = 0;
$column = 0;

$image = imagecreate($w,$h);
$black = imagecolorallocate($image,0,0,0);//Определяем черный цвет
$white = imagecolorallocate($image,255,255,255);//Белый
foreach($wordDot as $val)
    {
        //Если 0, то русуем белую точку, а если 1 - черную
        if($val == 0)   imageline($image,$column,$line,$column,$line,$white);
                else    imageline($image,$column,$line,$column,$line,$black);
        if($column == $w-1) {$line++; $column=-1;}
            $column++;
        
    }

//Сохраняем результат
imagepng($image,'./'.$fl.'.png');
imagedestroy($image);



Расшифровываем


echo "Input file: ";
$fly = readln();
if(file_exists($fly)) $image = imagecreatefrompng($fly); else die("File not found!\n");

//Вычисляем ширину и высоту изображения
        $w = imagesx($image);
        $h = imagesy($image);
//B количество пикселей в нем (S =a*b)
        $wh = $w*$h;
        $x = 0;
        $y = 0;

        for($t=0; $t < $wh; $t++)
            {
//Определяем цвет точки. 
                $rgb = imagecolorat($image, $x, $y);
                $colors = imagecolorsforindex($image, $rgb);
                $cl = $colors['red'].$colors['green'].$colors['blue'];
//Если белый цвет, то ставим 0, а если черный - 1
                if($cl == '255255255') $binary .= '0';
                if($cl == '000') $binary .= '1';
                if($x == $w-1) {$y++; $x=-1;}
                    $x++;
            }
//Переворачиваем и преобразовываем в текст
$dt = ascii_decrypt(strrev($binary));
//Записываем в файл
file_put_contents(str_replace('.png', '', $fly), $dt);


Запуск


У вас должен быть установлен интерпретатор PHP.

Linux (Unix): 

  • chmod +x classic.php
  • ./classic.php encrypt #Зашифровать
  • ./classic.php decrypt #Расшифровать


Windows:

  • path_to_php\php.exe classic.php encript #Зашифровать
  • path_to_php\php.exe classic.php decrypt #Расшифровать



Заключение


Если вам лень собирать весь код по кусочкам, то вот он целиком.


Этот код еще не годится для полноценного шифрования. Туда можно добавить еще пару десятков степеней шифрования: добавление соли, сжатие, преобразование всего в азбуку Морзе или в китайские символы. Это зависит от степени вашей извращенности изощренности. Я работаю над тем, чтобы он мог шифровать большие файлы. В скором времени хочу запустить сервис по шифрованию.


PS. При шифровании исполняемых файлов получается красивая картинка: 

XLiveAchiever.asi

MD5Inside.exe


PPS. Расшифруйте это сообщение ;) 

Расшифруй, что здесь написано ;)


Report Page