Архив за Июнь 2008

Защитное изображение для HTML-формы

Для защиты от автоматической регистрации в HTML-форму добавляют изображение со случайной последовательностью цифр и букв, которые выводятся пользователю в виде динамического изображения. Одновременно в сессию помещается случайная последовательность цифр. Пользователь должен ввести код, который он видит на изображении, в текстовое поле. Если код совпадает с сохраненным в сессии, можно с большой долей вероятности сказать, что сайт просматривает человек, поскольку робот обычно не решает задачу распознавания образов.

<?php

// Ширина изображения
$width = 150;
// Высота изображения
$height = 50;
// Количество символов в коде
$sign = 5;
// Защитный код
$code = '';
 
// Стартуем сессию
session_start();
 
// Символы, используемые в коде
$letters = array('A','B','C','D','E','F','G','H','J','K','M','N',
                 'P','Q','R','S','T','U','V','W','X','Y','Z',
                 '2','3','4','5','6','7','8','9');
// Компоненты для RGB-цвета
$figures = array(70, 90, 110, 130, 150, 170, 190);
// Создаем пустое изображение
$img = imagecreatetruecolor($width, $height);
 
// Заливаем фон белым цветом
$fon = imagecolorallocate($img, 255, 255, 255);
imagefill($img, 0, 0, $fon);

// Ширина поля под один символ
$letterWidth = intval((0.9*$width)/$sign);

// Заливаем фон точками
for($j=0; $j<$width; $j++) {
  for($i=0; $i<($height*$width)/600; $i++) {
    // Формируем случайный цвет
    $color = imagecolorallocatealpha(
             $img,
             $figures[rand(0,count($figures)-1)],
             $figures[rand(0,count($figures)-1)],
             $figures[rand(0,count($figures)-1)],
             rand(10,30));
    // Устанавливаем случайную точку случайного цвета
    imagesetpixel($img, rand(0,$width), rand(0,$height), $color);
  }
}

// Накладываем защитный код
for($i=0; $i<$sign; $i++)
{
  //Рисуем
  $color = imagecolorallocatealpha(
           $img,
           $figures[rand(0,count($figures)-1)],
           $figures[rand(0,count($figures)-1)],
           $figures[rand(0,count($figures)-1)],
           rand(10,30));

  // Генерируем случайный символ
  $letter = $letters[rand(0,sizeof($letters)-1)];

  // Формируем координаты для вывода символа
  if( empty($x) ) {
    $x = intval($letterWidth*0.2);
  } else {
    if( rand(0,1) )
      $x = $x + $letterWidth + rand(0, intval($letterWidth*0.1));
    else
      $x = $x + $letterWidth - rand(0, intval($letterWidth*0.1));
  }
  $y = rand( intval($height*0.7), intval($height*0.8) );
 
  // Размер шрифта символа
  $size = rand( intval(0.4*$height), intval(0.5*$height) );
  // Угол поворота символа
  $angle = rand(0, 30) - 15;
  // Запоминаем символ в переменной $code
  $code .= $letter;
  // Выводим символ на изображение
  imagettftext($img, $size, $angle, $x, $y, $color, "arialbd.ttf", $letter);
}
 
// Помещаем защитный код в сессию
$_SESSION['code'] = $code;
 
// Выводим изображение
header ("Content-type: image/jpeg");
imagejpeg($img);

?>

Скрипт позволяет создать изображение шириной $width и высотой $height пикселов, содержащее $sign случайных символов случайного цвета. Символы задаются массивом $letters, компоненты цвета — массивом $figures. После этого изображение заливается белым цветом, на котором размещаются в случайном порядке множество цветных пикселов, а затем генерируется и выводится случайный код $code. Переменная $code, помимо всего прочего, помещается в сессию, для того чтобы обработчик формы имел возможность сравнить введенный пользователем и сгенерированный коды. Так как данные из сессии не покидают сервер, злоумышленники не имеют возможности украсть защищенный код, сталкиваясь со сложной задачей распознавания образов.

Пример использования:

<?php
// Стартуем сессию
session_start();
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>Пример защиты формы</title>
</head>
<body>
<?php
if(isset($_POST['code']) && isset($_SESSION['code'])) {
  if($_POST['code'] == $_SESSION['code'])
    echo '<p style="color:green">Защитный код верен!</p>';
  else
    echo '<p style="color:red">Неверный защитный код!</p>';
  unset( $_SESSION['code'] );
} else {
  echo '<form action="'.$_SERVER['PHP_SELF'].'" method="post">';
  echo '<img src="captcha.php" border="0" alt="" /><br/>';
  echo '<input type="text" name="code" value="" /><br/>';
  echo '<input type="submit" name="submit" value="Отправить" />';
  echo '</form>';
}
?>
</body>
</html>

Ссылки по теме:

Права доступа на файлы (CHMOD)

Права доступа - это атрибуты файла или каталога, которые указывают серверу, кто и что может делать с соответствующим файлом или каталогом. Обычно, права доступа регламентируют такие действия как чтение, запись в файл (или каталог), исполнение.

В системах UNIX все пользователи разделяются на три группы: “user” (непосредственно владелец файла), “group” (член той же группы, к которой принадлежит владелец файла) и “other” (все остальные). Когда вы соединяетесь с сервером, он определяет к какой группе вы относитесь. Например, подключаясь к серверу по FTP, вы входите под своим именем пользователя, соответственно сервер относит вас к группе “user”. Другие пользователи, подключаясь по FTP, будет отнесены к группе “group”, а когда человек попадает к вам на сайт через свой браузер, то попадает в группу “other”.

После определения группы, пользователь получает права на действия с объектами. Т.е он может прочитать, записать или выполнить файл. Чтобы просмотреть каталог, он должен быть исполняемым; чтобы просмотреть его содержимое, он должен иметь атрибут чтения, а чтобы создать новый файл или каталог в существующем каталоге, необходимо иметь право на запись. Таким образом, чтобы выполнялось приложение или CGI скрипт, необходимо установить атрибут чтения и выполнения.

Чтобы распределить права для соответствующих групп, используются цифровые обозначения:

4 = read (право на чтение)
2 = write (право на запись)
1 = execute (право на выполнение)

Простым сложение цифр можно добиться установления прав на совокупность действий. Например, 3(2+1) разрешает запись и выполнение файла (каталога); 5(4+1) разрешает чтение и выполнение; 6(4+2) разрешает чтение и запись; 7(4+2+1) устанавливает право чтения, записи и выполнения. Т.е всего семь вариантов:

7 = read, write & execute
6 = read & write
5 = read & execute
4 = read
3 = write & execute
2 = write
1 = execute

Первая цифра в обозначении устанавливает права для группы “user”(т.е фактически для вас), вторая для группы “group” и третья для “other”:

755
для user - read, write & execute
для group - read & execute
для other - read & execute

Для установления прав доступа используется команда CHMOD. Во всех современных FTP клиентах присутствует возможность назначения прав доступа путем простановки “галочек” в чекбоксах, либо просто введением цифрового кода в соответствующее поле.

Команда “chmod” имеет два режима: Абсолютный(цифровой) и Символьный режим.

При абсолютном (цифровом) режиме используется описанный выше 3-х цифровой код прав доступа. Символьный режим использует буквенный формат для установки прав доступа. Здесь используются буквы “r”, “w” и “x” для read, write и execute соответственно. А также “u”, “g”, “o” и “a” для user, group, other, и all(все) соответственно.

Например:
755 : chmod u=rwx,go=rx filename
644 : chmod u=rw,go=r filename
600 : chmod u=rw,go= filename
444 : chmod a=r filename

Построение диаграмм средствами GDLib

Построение гистограммы

Пусть значения столбцов задаются в процентах от 0 до 100 в массиве $rows:

<?php
// Значение столбцов от 0 до 100
$rows = array(80, 75, 53, 32, 20);

// Ширина изображения
$width = 200;
// Высота изображения
$height = 200;
// Ширина одного столбца
$rowWidth = 30;
// Ширина интервала между столбцами
$rowInterval = 5;

// Создаем пустое изображение
$img = imagecreatetruecolor($width, $height);

// Заливаем изображение белым цветом
$white = imagecolorallocate($img, 255, 255, 255);
imagefill($img, 0, 0, $white);

for($i = 0, $y1 = $height, $x1 = 0; $i < count($rows); $i++) {
  // Формируем случайный цвет для каждого из столбца
  $color = imagecolorallocate($img, rand(0, 255), rand(0, 255), rand(0, 255));
  // Нормирование высоты столбца
  $y2 = $y1 - $rows[$i]*$height/100;
  // Определение второй координаты столбца
  $x2 = $x1 + $rowWidth;
  // Отрисовываем столбец
  imagefilledrectangle($img, $x1, $y1, $x2, $y2, $color);
  // Между столбцами создаем интервал в $row_interval пикселей
  $x1 = $x2 + $rowInterval;
}

// Выводим изображение в браузер, в формате GIF
header ("Content-type: image/gif");
imagegif($img);
?>

Результат работы скрипта:

Как видите, скрипт использует значения элементов массива $rows как процентные величины для формирования в цикле for гистограммы. На каждой итерации цикла формируется случайный цвет, который используется для отрисовки очередного столбца гистограммы. Столбец формируется при помощи функции imagefilledrectangle(), которая рисует заполненный прямоугольник.

Построение круговой диаграммы

Пусть доли секторов заданы массивом $row из предыдущего скрипта. При построении круговой диаграммы следут помнить, что в круге 360 градусов, и значения массива $rows следут нормировать таким образом, чтобы их сумма равнялась 360 градусам.

<?php
// Значения столбцов от 0 до 100
$rows = array(80, 75, 53, 32, 20);
// Нормируем значения массива $rows таким образом,
// чтобы их сумма составляла 360 градусов
$sum = array_sum($rows);
for($i = 0; $i < count($rows); $i++) {
  $rows[$i] = intval( round($rows[$i]*360/$sum) );
}

// Создаем пустое изображение размером 201x201 пикселей
$img =  imagecreatetruecolor(201, 201);
// Определение белого цвет на изображении
$white = imagecolorallocate($img, 255, 255, 255);
imagefill($img, 0, 0, $white);

// Переменные $cx и $cy определяют центр круговой диаграммы
$cx = $cy = 100;
// Переменные $w и $h определяют ширину и высоту диаграммы
$w = $h = 200;

$start = 0;
foreach ($rows as $value) {
  // Формируем случайный цвет для каждого сектора
  $color = imagecolorallocate($img, rand(0, 255), rand(0, 255), rand(0, 255));
  // Определяем конечный угол сектора
  $angle_sector = $start + $value;
  // Отрисовываем сектор
  imagefilledarc($img, $cx, $cy, $w, $h, $start, $angle_sector, $color, "IMG_ARC_PIE || IMG_ARC_EDGED");
  // Увеличиваем значение начального угла сектора
  $start += $value;
}
// Вывод изображения в окно браузера
header ("Content-type: image/gif");
imagegif($img);                     
?>

Результат работы скрипта: