Artykuł pochodzi z czasopisma PHP Solutions. Do ściągnięcia bezpłatnie ze strony:

Podobne dokumenty
7. Dynamiczne generowanie grafiki

Grafika PHP dla początkujących

Aplikacje WWW - laboratorium

I. Informacje ogólne. Jednym z takich systemów jest Mambo.

Kurs WWW. Paweł Rajba.

Część II Wyświetlanie obrazów

8. Dynamiczne generowanie grafiki, cz. 2

Ćwiczenie: JavaScript Cookies (3x45 minut)

Podstawy technologii WWW

Podstawy technologii WWW

Generatory pomocy multimedialnych

Materiały dla studentów pierwszego semestru studiów podyplomowych Grafika komputerowa i techniki multimedialne rok akademicki 2011/2012 semestr zimowy

Cała prawda o plikach grafiki rastrowej

FORMATY PLIKÓW GRAFICZNYCH

Konfiguracja szablonu i wystawienie pierwszej aukcji allegro

Kontrola sesji w PHP HTTP jest protokołem bezstanowym (ang. stateless) nie utrzymuje stanu między dwoma transakcjami. Kontrola sesji służy do

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

Formaty obrazów rastrowych biblioteki PBM

Tworzenie infografik za pomocą narzędzia Canva

Laboratorium 7 Blog: dodawanie i edycja wpisów

Backend Administratora

Grafika na stronie www

Aplikacje internetowe - laboratorium

GRAFIKA RASTROWA. WYKŁAD 2 Oprogramowanie i formaty plików. Jacek Wiślicki Katedra Informatyki Stosowanej

Smarty PHP. Leksykon kieszonkowy

Rozdział ten zawiera informacje o sposobie konfiguracji i działania Modułu OPC.

Baza danych do przechowywania użytkowników

etrader Pekao Podręcznik użytkownika Strumieniowanie Excel

Tworzenie szablonów użytkownika

Jak dodać własny szablon ramki w programie dibudka i dilustro

Scenariusz lekcji. Scenariusz lekcji. opisać działanie narzędzi przybornika. korzystać z Edytora postaci programu Logomocja;

INSTRUKCJE WIKAMP Dotyczy wersji systemu z dnia

Księgarnia internetowa Lubię to!» Nasza społeczność

TWORZENIE DANYCH DO DRUKU W PROGRAMIE MICROSOFT POWERPOINT 2013

KRYPTOGRAFIA I OCHRONA DANYCH PROJEKT

Dane - pobieranie, przekazywanie i przechowywanie. dr Beata Kuźmińska-Sołśnia

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ),

Poczta elektroniczna ( ) służy do przesyłania i odbierania listów elektronicznych np.: wiadomości tekstowych, multimedialnych itp.

e-sprawdzian instrukcja programu do sprawdzania wiedzy ucznia przy pomocy komputera (WINDOWS & LINUX)

PHICS - Polish Harbours Information & Control System Dokumentacja użytkownika System weryfikacji autentyczności polskich dokumentów marynarzy

Zmienne i stałe w PHP

Grafika rastrowa (bitmapa)-

Rozszerzenia plików graficznych do publkacji internetowych- Kasia Ząbek kl. 2dT

Jak ustawić cele kampanii?

Pomoc dla systemu WordPress

Dokumentacja systemu NTP rekrut. Autor: Sławomir Miller

Zalogowanie generuje nowe menu: okno do wysyłania plików oraz dodatkowe menu Pomoc

Pierwsza strona internetowa

// Potrzebne do memset oraz memcpy, czyli kopiowania bloków

Jak przygotować? Wymiary reklam: Spad. Bez spadu

Instrukcja krok po kroku w darmowym programie PhotoScape

Wysyłanie pliku na serwer. Plik na serwerze.

14. POZOSTAŁE CIEKAWE FUNKCJE

Tworzenie prezentacji w MS PowerPoint

PHP: bloki kodu, tablice, obiekty i formularze

autor poradnika - KS Jak zamieszczać i edytować artykuły na szkolnej stronie internetowej

Grafika komputerowa. Dla DSI II

Dokumentacja WebMaster ver 1.0

Zakres treści Czas. 2 Określenie charakteru i tematyki strony. Rodzaje witryn. Projekt graficzny witryny. Opracowanie skryptów

MS Word Długi dokument. Praca z długim dokumentem. Kinga Sorkowska

Być może jesteś doświadczonym programistą, biegle programujesz w Javie,

EDYCJA TEKSTU MS WORDPAD

Zawartość specyfikacji:

Instrukcja - blogi OK zeszyt Logowanie

Przy dużej wielkości głębokości uzyskamy wrażenie nieskończoności: Dla głębokości zerowej uzyskamy tekst płaski:

Wprowadzenie do Internetu Zajęcia 5

Formaty plików graficznych

Po zakończeniu rozważań na temat World Wide Web, poznaniu zasad organizacji witryn WWW, przeczytaniu kilkudziesięciu stron i poznaniu wielu nowych

1.2 Logo Sonel podstawowe załoŝenia

Technologie Internetowe Raport z wykonanego projektu Temat: Internetowy sklep elektroniczny

Pokaz slajdów na stronie internetowej

Tworzenie własnych map dla UI-View

1. Pobieranie i instalacja FotoSendera

Dokumentacja fillup - MS SQL

Obsługa programu Paint. mgr Katarzyna Paliwoda

Instrukcja użytkownika

GRAFIKA RASTROWA. WYKŁAD 1 Wprowadzenie do grafiki rastrowej. Jacek Wiślicki Katedra Informatyki Stosowanej

STRONY INTERNETOWE mgr inż. Adrian Zapała

Umieszczanie kodu. kod skryptu

,Aplikacja Okazje SMS

Projektowanie przy uz yciu motywo w częś c 1: informacje podśtawowe

narzędzie Linia. 2. W polu koloru kliknij kolor, którego chcesz użyć. 3. Aby coś narysować, przeciągnij wskaźnikiem w obszarze rysowania.

WORDPRESS INSTRUKCJA OBSŁUGI

GRAFIKA. Rodzaje grafiki i odpowiadające im edytory

APLIKACJA SHAREPOINT

Funkcje i instrukcje języka JavaScript

Aplikacje WWW - laboratorium

AutoCAD LT praca na obiektach rastrowych i nakładanie barw z palety RGB na rysunki.

INTERNETOWE BAZY DANYCH materiały pomocnicze - wykład VII

1. Przypisy, indeks i spisy.

Instalacja (GM) AMXBans #1.5.1/ #1.6.1 na serwerze gry/stronie WWW. Wymagania

Wstawianie nowej strony

TWORZENIE PREZENTACJI MS POWERPOINT

Warunki techniczne prezentacji reklam

Wirtualna tablica. Padlet: Padlet nazywany jest wirtualną tablicą, ścianą lub kartką strony internetowej.

Tworzenie menu i authoring w programie DVDStyler

Zawartość. Wstęp. Moduł Rozbiórki. Wstęp Instalacja Konfiguracja Uruchomienie i praca z raportem... 6

Projektowanie stron WWW

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

Transkrypt:

Artykuł pochodzi z czasopisma PHP Solutions. Do ściągnięcia bezpłatnie ze strony: www.phpsolmag.org Bezpłatne kopiowanie i rozpowszechanie artykułu dozwolone pod warunkiem zachowania jego obecnej formy i treści.

Wojciech Jukowski Powstrzymywanie automatów obrazki z napisami Wymuszenie, by użytkownik przeczytał i wpisał w pole formularza napis znajdujący się na rysunku to nie tylko sposób by zdenerwować odwiedzającego stronę. To także jedna ze skuteczniejszych metod zabezpieczania witryn przed atakami automatów, mającymi na celu np. zdobycie dostępu do serwera. Rozwiązanie tego typu stosowane jest m.in. Przez portal Yahoo! podczas tworzenia konta użytkownika. W artykule przedstawię budowę mechanizmu do generowania tokenów, zaproponuję też kilka ulepszeń uniemożliwiających automatom czytanie napisów z rysunków. Do generowania grafiki wykorzystam popularną, dostępną bezpłatnie, bibliotekę GD. Biblioteka GD zależnie od wersji wspiera tworzenie grafiki w formacie JPEG, PNG, WBMP oraz XPM. Starsze wersje (do 1.6) umożliwiały również tworzenie obrazków GIF. W związku z potrzebą posiadania licencji na algorytm kompresji użyty w plikach GIF, wsparcie dla formatu GIF zostało w bibliotece zastąpione wsparciem dla formatu PNG. Jest jednak możliwe uzyskanie zgody na legalne wykorzystywanie formatu GIF wraz ze starszymi bibliotekami GD. Nie jest to jednak łatwe i możliwe, że będzie sporo kosztowało. Po szczegóły na temat uzyskania dostępu do opatentowanego algorytmu odsyłam na stronę: http: //www.unisys.com/about unisys/lzw. W artykule opisywać będę tworzenie obrazków typu PNG. To najbardziej wszechstronny format. Dobrze wspiera dużą ilość kolorów, pozwala na przeźroczystość oraz jest obsługiwany przez większość przeglądarek. Zestawienie wszystkich wspieranych typów wraz z krótkim opisem zawiera Ramka 2. Aby sprawdzić, czy mam zainstalowaną bibliotekę GD tworzę skrypt z wywołaniem funkcji phpinfo(). Pośród długiej listy, jaką daje wynik, znajduję informacje o bibliotece GD. Oznacza to, że biblioteka jest ładowana do PHP. Ramka może wyglądać, jak ta na Rysunku 4. Krok 1. Wybieramy rozmiar obrazka 1 www.phpsolmag.org PHP Solutions 1/2003

Rysunek 1. Tak przebiega rozwój naszego tokena Instalacja biblioteki Pracując w dowolnym systemie z rodziny Windows otwieram plik php.ini. Znajduję linijkę: extension=php _ gd.dll i odkomentowuję ją, to znaczy usuwam średnik z początku linii. Nowsze wersje PHP mogą zawierać wsparcie dla biblioteki GD w wersji 2 wówczas dyrektywa extension będzie wskazywała na plik php_gd2.dll. PHP będzie szukało pliku biblioteki w katalogu extension _ dir, sprawdzam więc, na jaki katalog w php.ini wskazuje ta zmienna i w razie potrzeby poprawiam wpis. Jeśli w katalogu extensions/ lub innym, na który wskazuje extension _ dir, nie ma odpowiedniego pliku.dll należy pobrać pełną wersje pakietu ze strony http://www.php.net/ downloads.php. Rysunek 2. Informacja o bibliotece GD Krok 2. Wypełniamy tło PHP Solutions 1/2003 www.phpsolmag.org 2

Listing 1. Tworzenie obrazka z napisem <?php?> //tworzę obrazek o określonych //wymiarach $grafix = ImageCreate(25 100); //tworzę dwa kolory zielony //i niebieski (tło) $bgcolor = ImageColorAllocateS ($grafix, 255, 0); //kolor tekstu $txtcolor = ImageColorAllocateS ($grafix, 255); //maluję tło na zielono ImageFill($grafix, 25 10 $bgcolor); //umieszczam niebieski napis //"Alice in Wonderland" //rozmiaru 3 ImageString($grafix, 6, 15, 15, "Alice in Wonderland", $txtcolor); //wysyłam odpowiedni nagłówek, //a następnie obrazek do //przeglądarki header("content-type: image/png"); ImagePNG($grafix); //sprzątam po sobie ImageDestroy($grafix); Rysunek 3. Schemat działania Projekty W systemie Linux konieczne jest wkompilowanie biblioteki GD do systemu (może się to sprowadzić wyłącznie do dodania odpowiedniego pakietu). (Informacje o instalacji rozszerzenia zawiera Ramka 3). Po dodaniu biblioteki należy pamiętać o modyfikacji pliku konfiguracyjnego PHP (domyślna lokalizacja to /etc/php.ini). Tak jak w przypadku Windows należy odkomentować odpowiednią dyrektywę extension oraz sprawdzić wskazanie dla extension _ dir. Zamiast płótna i pędzla skrypt Jeśli biblioteka GD jest zainstalowana i działa prawidłowo powinno udać się stworzyć obrazek. W tym celu piszę prosty skrypt mający wygenerować Krok 3. Dodajemy napis Zestawienie formatów graficznych dostępnych w bibliotece GD GIF (Graphics Interchange Format) jest to formuła zapisu plików graficznych stworzona przez firmę CompuServ w roku 1987. Do ich tworzenia wykorzystywany jest algorytm kompresji (LZW) stworzony i opatentowany przez firmę Unisys. Jako iż Unisys czerpie korzyści ze swego patentu, używanie zapisu GIF wymaga posiadania licencji. W sierpniu 2004 roku, patent przestanie obowiązywać na całym świecie. Jak podają autorzy biblioteki GD powróci wówczas usunięty format. GIF pozwala tworzyć obrazki z zadeklarowanym kolorem przeźroczystym. Obsługuje do 256 kolorów. Dzięki małym rozmiarom oraz możliwości tworzenia animacji szybko zyskał ogromną popularność w Internecie. JPEG/ JPG (Joint Photographic Experts Group) kolejny niezwykle popularny w internecie format. Pozwala na 24 bitowy zapis koloru (ponad 16 milionów kolorów). Znakomity do fotografii czy tonalnych przejść barw. Przy małych obrazkach, kompresja może czynić obrazek miejscami rozmazany lub nieczytelny. PNG (Portable Network Graphics) następca formatu GIF. Oferuje lepsze wsparcie dla kolorów i doskonalszą kompresję. Pozwala na zmianę natężenia światła i ma wsparcie dla przeźroczystości. WBMP format stworzony na potrzeby protokołu WAP. To bitmapa o tylko dwóch kolorach (czarnym i białym). Obrazki WBMP prócz telefonów komórkowych poprawnie interpretuje ten format tylko jedna przeglądarka Opera. XMP wymaga systemu X-Window. Więcej informacji o bibliotece i jej możliwościach można znaleźć na stronie http://www.bountell.com/gd/ 3 www.phpsolmag.org PHP Solutions 1/2003

Powstrzymywanie automatów Listing 2. Przesłanie nagłówka do przeglądarki header ( "Expires: Mon, 22 Sep 1997 09:00:00 GMT"); header ( "Last-Modified: ". gmdate("d, d M Y H:i:s"). " GMT"); header ( "Cache-Control: no-store, no-cache, must-revalidate"); header ( "Cache-Control: post-check= pre-check=0", false); header ("Pragma: no-cache"); obiekt typu PNG, szeroki na 250 i wysoki na 100 pikseli (Listing 1). Krótko o kodzie z Listingu 1. Skrypt zaczynam funkcją ImageCreate tworzącą obrazek. Za pomocą funkcji ImageColorAllocate definiuję odcienie, których zamierzam użyć przy kolorowaniu obrazka. Nasycenie barw czerwonej, zielonej i niebieskiej, (czyli RGB) podaje w kolejnych parametrach. W następnej linii wywołuję ImageFill by pokolorować tło (całe więc parametry mają wielkość obrazka, czyli 250 i 100 pikseli. Następnie umieszczam tekst Alice in Wonderland, przekazując ImageString zmienne dotyczące napisu. ImageString przyjmuje kolejno wartości: obrazek, rozmiar wyświetlanego tekstu (6 odległość od lewego brzegu (15) i odległość od górnej krawędzi (15 napis, jaki ma się pojawić oraz kolor tekstu. Ostatnie linie to wysłanie odpowiedniego nagłówka Listing 3. Losowanie słowa if(phpversion()< 4.2){ mt_srand(time()*123456); $words = "Alice", "cat", "rabbit", "Queen"); $randwordno = mt_rand( sizeof($words)-1); ImageString( $grafix, 6, 15, 15, $words[$randwordno], $txtcolor); do przeglądarki, wyświetlenie grafiki i usunięcie obrazka z pamięci. Może się okazać, że nasza wersja biblioteki nie wspiera PNG (za to radzi sobie z plikami JPEG bądź GIF) wówczas wszystkie wywołania ImagePNG w listingach należy zastąpić odpowiednio ImageJpeg lub ImageGif. Niektóre przeglądarki buforują otrzymane dane, szczególnie gdy jest to grafika. Aby przeglądarka za każdym razem pobierała tworzoną grafikę, należy dopisać na początku skryptu nagłówki wymuszające każdorazowe pobieranie wygenerowanej zawartości (Listing 2). Przesyłamy obraz Jestem w stanie wygenerować obrazek, czyli biblioteka GD działa poprawnie. Określiłem, jakie nagłówki należy przesłać do przeglądarki by nie buforowała danych. Mogę zająć się stworzeniem formula- Listing 4. Formularz <?php session_name("imagesess"); session_start(); //sprawdzanie formularza $show = "form"; if(isset($_post["guessedword"])) { if($_post["guessedword"] == $_SESSION["choosenWord"]){ $show = "OK"; else{ $show = "error"; if($show == "form" $show == "error"){ if($show == "error"){ echo "Nie odgadłeś słowa. Spróbuj ponownie";?> <form method="post" action="<?=$_servers ["PHP_SELF"]?>"> <img src= "grafixtoken.php?imagesess= <?=session_id()?>"> <input type="text" name="guessedword"> <input type="submit" value="sprawdź mnie"> </form>?> <? else{ echo "Gratulacje poprawnego odczytania słowa!"; Rysunek 4. Generowany automatycznie obrazek (token) na stronie Yahoo Krok 4. Różne napisy PHP Solutions 1/2003 www.phpsolmag.org 4

Projekty Listing 5. Losowanie kolorów dla tła i napisu $settings= "bgcolor" => 255, 0 "txtcolor"=> 255, 0) "bgcolor" => 255, 0 "txtcolor"=> 255) "bgcolor" => 255 "txtcolor"=> 255, 0) ) ); $randsettingsno = mt_rand( sizeof($settings)-1); //kolor tła $bgcolorrgb = $settings[ $randsettingsno ]["bgcolor"]; $bgcolor = ImageColorAllocate( $grafix, $bgcolorrgb[0], $bgcolorrgb[1], $bgcolorrgb[2]); //kolor tekstu $txtcolorrgb = $settings[ $randsettingsno ]["txtcolor"]; $txtcolor = ImageColorAllocate( $grafix, $txtcolorrgb[0], $txtcolorrgb[1], $txtcolorrgb[2]); Listing 6. Losowa zmiana parametrów obrazka $settings= "bgcolor" => mt_rand(3180 mt_rand(30) "txtcolor"=> mt_rand(15255 mt_rand(30)) "bgcolor" => 255, mt_rand(3180 0 "txtcolor"=> mt_rand(30 mt_rand(10255)) "bgcolor" => mt_rand(3180 mt_rand(30) "txtcolor"=> mt_rand(10230 mt_rand(15255)) ) ); rza. Zawierał on będzie obrazek z treścią, którą odczyta użytkownik. Całość podzieliłem na dwa osobne pliki (skrypty). Pierwszy służy do obsługi generowanej grafiki zawierającej losowy napis, drugi zawiera skrypt wyświetlający formularz oraz sprawdzający, czy wpisane informacje są prawidłowe. Do przekazywania informacji, jakie słowo znajduje się na obrazku, pomiędzy plikami (skryptami) użyję sesji. W pierwszej kolejności opiszę kod generujący obrazek. Aby przekazać wartość korzystając z sesji, trzeba ją wystartować. Na początku skryptu umieszczam session _ name("imagesess"); session _ start();. Nadając nazwę sesji (do tego używam session _ name) mam pewność do jej nazwy i nie muszę pobierać jej później. Modyfikuję skrypt z Listingu 1 dodając pierwsze utrudnienie losowanie słowa z tablicy. Wywołanie funkcji ImageString poprzedzam odpowiednim wpisem (patrz Listing 3). W PHP starszym niż 4.2 należy dodać wywołanie generatora liczb losowych przed pierwszym wywołaniem mt _ rand, nowsze wersje PHP nie wymagają jego inicjowania. Jak wcześniej napisałem, przekazuję przez sesję wylosowane słowo. Dodaję linię: $_SESSION["choosenWord"] = $words[$randwordno]; Wraz z rozbudową programu pojawią się kolejne utrudnienia. Zajmę się teraz częścią drugą, zawierającą formularz (Listing 4). Koniecznie należy pamiętać o wystartowaniu sesji. Najpierw sprawdzam, czy istnieje zmienna guessedword przesłana metodą POST. Prawda (true) oznacza, że wypełniono formularz. Sprawdzam więc, czy wylosowane słowo dokładnie odpowiada przesłanej wartości: $_POST["guessedWord"] == $_SESSION["choosenWord"]. Rezultat przekazuję do zmiennej $show, która ma wartość OK jeśli wszystko się zgadza, albo error, gdy ktoś źle odczytał słowo. Ten etap zatrzymuje wszystkie popularne automaty do pobierania stron takie jak Wget czy Teleport Pro. Skrypt można jeszcze rozwinąć. Dodatkowe zabezpieczenia pozwolą uniknąć prób odczytania napisu z obrazka przez programy wykorzystujące metodę OCR (Optical Character Recognition, czyli Krok 5. Zmieniamy kolor tła Rysunek 5. Strona główna projektu CAPTCHA 5 www.phpsolmag.org PHP Solutions 1/2003

Powstrzymywanie automatów Listing 7. Opis tapety Listing 8. Tapeta Listing 9. Losowa czcionka $settings= "wallpaper" => "./wallpapers/ wallpaper1.png", "bgcolor" => mt_rand(3180 mt_rand(30) "txtcolor" => mt_rand(15255 mt_rand(30)) "wallpaper" => "./wallpapers/ wallpaper2.png", "bgcolor" => 255, mt_rand(3180 0 "txtcolor" => mt_rand(30 mt_rand(10255)) "bgcolor" => mt_rand(3180 mt_rand(30) "txtcolor" => mt_rand(10230 mt_rand(15255)) ) ); rozpoznanie pisma przez komputer). Aby wprowadzić je w błąd, stosujemy jak najwięcej nieregularności i drobnych zniekształceń pozwalających jednak odczytać napis przez człowieka. Losowa pozycja napisu, losowy kolor tła Utrudnienia zacznę od nieregularnego umieszczenia napisu na obrazku. Wystarczy, że w wywołaniu funkcji ImageString zmienię stałą odległość od lewego brzegu i od góry na wartość losową. Oto moje zmiany: $randspaceleft = mt_rand(200); $randspaceup ImageString($grafix, 6, = mt_rand(70); if(isset( $settings[ $randsettingsno ] ["wallpaper"])){ //otwieram obrazek typu PNG $grafixbackground = @ImageCreateFromPng( $settings[ $randsettingsno ] ["wallpaper"]); //kopiuję całą zawartość //na $grafix ImageCopy($grafix, $grafixbackground, 25 100); else{ ImageFill($grafix, 25 10 $bgcolor); $randspaceleft, $randspaceup, $words[$randwordno], $txtcolor); Należy zwrócić uwagę, by nie przesadzić z górną wartością zakresu mt _ rand() nie chcemy przecież, żeby słowo wylądowało poza widocznym obszarem. Sprawdzam więc, czy napis mieści się na rysunku, wpisując najdłuższe słowo. Wybieram też, najwyższe wartości dla odległości od lewego i górnego rogu (w moim przypadku odpowiednio 200 i 70). Również wybór tła i kolor napisu pozostawię losowaniu (patrz Listing 5). Wpierw definiuję tablicę $settings, składającą się z kilku tablic. Każda tablica składowa zawiera po dwa klucze: bgcolor oraz txtcolor. Następnie losuję jeden zestaw spośród dostępnych i przypisuję odpowiednie wartości do zmiennych $txtcolorrgb oraz $bgcolor- RGB. W ten sposób obie zmienne przechowują tablicę trzech wartości odpowiadających kolejno barwom Red (czerwony Green (zielony) oraz Blue (niebieski). Aby definicje RGB przełożyć na kolor występujący na obrazku, używam funkcji ImageCollorAllocate, a wynik zapisuję w $bgcolor i $txtcolor. Tych dwóch zmiennych użyję odpowiednio w wywołaniu ImageFill i ImageString. Dodaję kolejne drobne utrudnienie. Zamiast deklarować wartości RGB, odwołuję się do funkcji mt _ rand(). Za jej pomocą losuję wartości liczbowe, według zadanych parametrów. W ten sposób tworzę losowe barwy zarówno dla tła jak i tekstu. Należy jednak uważać, by kolor tła nie był zbyt bliski kolorowi napisu trudno będzie wówczas coś odczytać (patrz Listing 6). if(true == function_exists("imagettftext")) { $fontslist = "./fonts/ariblk.ttf", "./fonts/verdana.ttf", "./fonts/tahoma.ttf"); $randfontno = mt_rand( sizeof( $fontslist)-1); $randfontpath = realpath($fontslist[ $randfontno ]); $randspaceleft = mt_rand(170); $randspaceup = mt_rand(15,75); ImageTtfText( $grafix, 26, $randspaceleft, $randspaceup, $txtcolor, $randfontpath, $words[$randwordno]); else{ $randspaceleft = mt_rand(200); $randspaceup = mt_rand(50); ImageString( $grafix, 6, $randspaceleft, $randspaceup, $words[$randwordno], $txtcolor); Zabezpieczenia losowanie tapety i czcionki Idąc za ciosem, można zamiast koloru tła, użyć tapety tła w postaci obrazka. Dodajmy do niektórych zestawów klucz Krok 6. Dodajemy teksturę, modyfikujemy rodzaj czcionki i pochylenie napisu PHP Solutions 1/2003 www.phpsolmag.org 6

Projekty Listing 10. Poszerzenie tablicy $settings o noisecolor oraz definicja koloru $settings= "wallpaper" => "./wallpapers/wallpaper1.png", "bgcolor" => mt_rand(3180 mt_rand(30) "txtcolor" => mt_rand(15255 mt_rand(30) "noisecolor" => 20 mt_rand(15 250 mt_rand(10)) "wallpaper" => "./wallpapers/wallpaper2.png", "bgcolor" => 255, mt_rand(3180 0 "txtcolor" => mt_rand(30 mt_rand(10255) "noisecolor" => 20 mt_rand(30 mt_rand(185, 255)) "bgcolor" => mt_rand(3180 mt_rand(30) "txtcolor" => mt_rand(10230 mt_rand(15255) "noisecolor" => 10 mt_rand(15230 mt_rand(18 200) ) ) ); $randsettingsno = mt_rand( sizeof($settings)-1); //kolor tła $bgcolorrgb = $settings[ $randsettingsno ]["bgcolor"]; $bgcolor = ImageColorAllocate($grafix, $bgcolorrgb[0], $bgcolorrgb[1], $bgcolorrgb[2]); //kolor tekstu $txtcolorrgb = $settings[ $randsettingsno ]["txtcolor"]; $txtcolor = ImageColorAllocate($grafix, $txtcolorrgb[0], $txtcolorrgb[1], $txtcolorrgb[2]); //kolor zanieczyszczeń $noisecolorrgb = $settings[ $randsettingsno ]["noisecolor"]; $noisecolor = ImageColorAllocate($grafix, $noisecolorrgb[0], $noisecolorrgb[1], $noisecolorrgb[2]); wallpaper, wskazujący na ścieżkę do obrazka. Jeśli zostanie on zdefiniowany, zastąpi jednolitą barwę tła. Zmieniam, więc $settings (Listing 7). Musimy również dodać warunek poprzedzający wywołanie ImageFill (Listing 8). Wybór losowej czcionki jest kolejną przeszkodą dla automatów. Ten krok dostępny jest jedynie dla wybranych trzeba bowiem mieć zestaw czcionek (TrueType) oraz bibliotekę GD wspierającą tę opcję. Jeśli w phpinfo( w ramach informacji o bibliotece GD, znajduje się informacja FreeType Support: enabled, można ładować inne czcionki niż standardowe. Mój skrypt będzie działał na różnych serwerach sprawdzam więc, czy istnieje funkcja Krok 7. Dodatkowe litery w tle ImageTtfText. Jeśli funkcja jest dostępna wywołanie function _ exists zwróciło wartość TRUE - mogę korzystać z czcionek TrueType (.ttf). Gdy funkcja nie istnieje, korzystać będę nadal z ImageString. Dodaję od razu losowanie czcionki z listy (Listing 9). Kolejne parametry ImageTtfText oznaczają: grafikę, na której tekst ma się pokazać, rozmiar czcionki w pikselach, kąt nachylenia napisu, odległość podstawy pierwszej litery od lewego rogu, odległość podstawy pierwszej litery od góry, kolor tekstu, pełną ścieżkę do czcionki i, na końcu, sam napis, który ma się pokazać. Muszę od razu poprawić zakresy dla funkcji mt _ rand() losującej odległość od lewego i górnego brzegu obrazka. Kąt pochylenia napisu (czyli 3. parametr) można zastąpić wartością losową np. mt _ rand(-15,15 gdzie liczba oznacza ilość stopni. Do tworzenia grafiki wybrałem 3 czcionki, można jednak bez obaw losować z dużo większej listy. Ważne, by nie podać przez pomyłkę czcionki obrazkowej. Listing 11. Dodatkowe litery w tle grafiki (dla ImageTTFText) //losowe znaki w tle właściwego //napisu ImageTTFText for($i=1; $i<30; $i++){ $randcharspaceleft = mt_rand( 250); $randcharspaceup = mt_rand( 100); $randchar = chr(mt_rand(45, 250)); ImageTtfText( $grafix, 15, mt_rand(360 $randcharspaceleft, $randcharspaceup, $noisecolor, $randfontpath, $randchar); Powstrzymywanie wyrafiniowanych mechanizmów zanieczyszczanie obrazka Zmienianie tła lub czcionki nie gwarantuje, że obrazek nie zostanie odczytany przez sprytne programy wykorzystujące technikę OCR. Aby je zmylić, wynikowy obrazek zanieczyszczam. Najpierw dodaję losowe znaki w podkładzie właściwego napisu. Kolor liter musi być jaśniejszy od właściwego napisu, dlatego dokładam stosowane definicje kolorów do tablicy $settings, a po wylosowaniu zestawu wybieram nowy kolor (Listing 10). Następnie poprzedzam wywołanie funkcji ImageTTFText() Listingiem 11. Chcę by tło zawierało dodatkowe 30 znaków zanieczyszczających. Dla każdej iteracji pętli for() losuję pozycję litery. Symbol nie musi być widoczny w całości, może np. wyjechać poza Listing 12. Dodatkowe litery w tle grafiki (dla ImageString) for($i=1; $i<30; $i++){ $randcharspaceleft = mt_rand( 250); $randcharspaceup = mt_rand( 100); $randchar = chr(mt_rand(45, 250)); ImageString( $grafix, 4, $randcharspaceleft, $randcharspaceup, $randchar, $noisecolor); 7 www.phpsolmag.org PHP Solutions 1/2003

Powstrzymywanie automatów Listing 13. Przypadkowo rozmieszczam kolorowe kreski for($i=1;$i<50;$i++){ $randpixspaceleft = mt_rand( 250); $randpixspacetop = mt_rand( 100); $style = mt_rand(2); if(0 == $style){ ImageLine( $grafix, $randpixspaceleft, $randpixspacetop, $randpixspaceleft+1 $randpixspacetop+7, $txtcolor); elseif(1 == $style){ ImageLine( $grafix, $randpixspaceleft, $randpixspacetop, $randpixspaceleft-3, $randpixspacetop+7, $noisecolor); else{ ImageLine( $grafix, $randpixspaceleft, $randpixspacetop, $randpixspaceleft+5, $randpixspacetop-5, $bgcolor); obszar obrazka. Podaję więc zakresy równe wymiarom obrazka. Następnie losuję znak w kodzie ASCII pomiędzy 45 a 25 po czym wyświetlam go. Jak napisałem wcześniej, nie chcę, by wylosowane znaki myliły człowieka symbol będzie więc miał mniejszy rozmiar (20). Pozwalam też na sporą dowolność w jego położeniu (kąt pochylenia nawet do 360 stopni). Nie zawsze dostępna jest funkcja ImageTTFText( dodaję więc odpowiednie linie poprzedzając wywołanie funkcji ImageString (Listing 12) W ten sposób dołożę zanieczyszczone litery również wtedy, gdy nie mogę ładować czcionek True Type. Aby ostatecznie zmylić automaty pozwalam sobie na jeszcze jedną sztuczkę: na wynikowym obrazku umieszczę kilkadziesiąt malutkich kresek. Ich nieregularne położenie oraz różne kolory powinny udaremnić pracę programom szukającym liter lub wyrazów na obrazkach. Chcę by linie przykrywały właściwy napis dodaję je dopiero po wywołaniu ImageString lub ImageTTFText (Listing 13). Odrobina historii Problem automatycznego wypełniania formularzy przez automaty nie jest młody. W roku 1997 najpopularniejsza wówczas wyszukiwarka internetowa Altavista potrzebowała sposobu, by powstrzymać automaty przed dopisywaniem do bazy stron WWW. Dodano wówczas zabezpieczenie na etapie procesu rejestracji konta: konieczność odczytania napisu z obrazka. W 2000 roku Yahoo! postanowiło rozwiązać problem dotyczący rejestracji i działań w serwisie dokonywanych przez automaty, które były programami rejestrującymi się pod rzeczywistych użytkowników. Sztuczne twory poruszały się po serwisie, często działając jako nadawcy niechcianej poczty (tj. spamu). By znaleźć rozwiązanie tego problemu zespół z Carnegie Mellon University oraz John Langford z IBM stworzyli CAPTCHA ( completely automated public Turing test to tell computers and humans apart automatyczny test Turinga odróżniający ludzi i komputery). Program miał na celu stworzenie zadania, którego komputery nie będą w stanie rozwiązać bezbłędnie, za to ludzie pokonają z łatwością. Zaproponowano kilka rozwiązań, z których najbardziej godnym zaufania systemem okazał się Gimpy. Mechanizm opiera się na ludzkiej możliwości odczytania nawet bardzo zniekształconego tekstu. Został zaprojektowany przy współpracy z portalem Yahoo! Przykład niewiele zmodyfikowanego pomysłu Gimpy (Ez-Gimpy) pokazuje Rysunek 2. Innymi rozwiązaniami, należącymi do projektu CAPTCHA są: Bongo (użytkownik musi poprawnie przyporządkować elementy do właściwych grup PIX (znalezienie wspólnego określenia dla grupy obrazków Byan (rozpoznanie słów w różnych tonach). Więcej o każdym z systemów można znaleźć na domowej witrynie projektu: http://www.captcha.net Mój obrazek nie jest duży, więc dodam 50 kresek. Dla każdej losuję początek (odległość od lewego i górnego brzegu). Później wybieram styl. Zależnie od wartości linia będzie prawie płaska, lekko lub ostro pochylona. Styl określa również długość oraz kolor linii używam wszystkich trzech zdefiniowanych wcześniej kolorów: $txtcolor, $bgcolor oraz $noise- Color. W ten sposób zniekształcony obrazek powinien stanowić wystarczające zabezpieczenie przed automatami mają- Rysunek 7. Aurox Live PHP cymi na celu uzyskanie dostępu do serwisu internetowego. Podsumowanie Przedstawione w artykule propozycje utrudnienia odczytania napisu z grafiki nie wyczerpują tematu. Można używać trzech słów zamiast jednego czy nakładać je na siebie. Można też odwoływać się do zespołu obrazów zawierających wspólne przesłanie: zamiast umieszczania grafiki odtwarzać dźwięki, tworzyć animacje. Ogranicza nas tylko nasza wyobraźnia. PHP Solutions 1/2003 www.phpsolmag.org 8