Proste szyfrowanie

6 06 2010

Dawno już nie pisałem i z całą pewnością wyszedłem już z wprawy. Od czasu ostatniego mojego wpisu miałem mnóstwo tematów i pomysłów do blogowania jednak mimo wszystko nie znalazłem na to ani chwili czasu.

Całkiem niedawno stanąłem przed małym problemem natury raczej algorytmicznej. W czasach kiedy kradzież contentu jest coraz bardziej powszechna, a ludzie czynią to bez krzty sumienia dostałem do pracy małą modyfikacje.
Z baza danych pewnego serwisu, o którym pisać tu nie mam zamiaru wczytywane były rekordy według pewnego wzorca:

domena.pl/index.php?id=231

Aby uniknąć parserowego pobierania zawartości miałem między innymi zmodyfikować sposób prezentowania linków. Czyli szybka transformacja do:

domena.pl/gVw8zQ.

W podobny sposób prezentowane są linki w tak popularnym serwisie jak YouTube.com czy w niektórych miejscach portalu o grach komputerowych. W swoim artykule zajmę się ostania część adresu, która charakteryzuje się niepowtarzalnością i ma być moim kluczem według którego wpisy będą pobierane z bazy. Do rzeczy!

Dla ustalenia uwagi mam takie oto id: 1823042. Chcę je w jakiś w miarę logiczny sposób przekształcić do postaci jakiegoś string’a. Stworzyłem sobie tablicę cyfr oraz odpowiadającą im tablicę liter.

$cyfra = array(0=>'akwGR0', 'blxHS1', 'cmyIT2', 'dnzJU3', 'eoAKW4', 'fpBLX5', 'grCMY6', 'hsDNZ7', 'itEOx8', 'juFPy9');

Gdybym przyjął, że cyfra 1 to litera C, 5 – g, 8 – m itd. to gdyby ktoś dotarł do mojego algorytmu w łatwy sposób uczyniłby moją pracę bezcelową. Przy założeniu (w moim przypadku), że liczba jest 7 cyfrowa mamy: Każda cyfra ma 6 odpowiedników literowych. Czyli właściwie liczba 1823042 może być zakodowana na [C_{6}^{1}]^7 sposobów = 6*6*6*6*6*6*6. Aż strach to nawet liczyć!

Prostą pętelką while podzielę dużą liczbę na pojedyncze cyfry. Wykorzystam tutaj odpowiedniki DIV i MOD znane choćby z DELPHI.


while($liczba>0)
{
$reszta=$liczba%10;
$code.=$cyfra[$reszta][rand(0,5)];

$liczba=($liczba-$reszta)/10;
}

Część z moich wykładowców rzekłaby: „Hohoho! A gdzie tabelka egzekucji!”. Przedstawię więc ją tutaj dość schematycznie:


START
code:='';
$liczba:=3211;
1 – $cyfra[1][rand(0,5)] //wylosowałem liczbę 3.
$cyfra[1][3]=’H';
code:=’H';
$liczba := (3211-1)/10=321
1 – $cyfra[1][rand(0,5)] //wylosowałem liczbę 1.
$cyfra[1][1]=’l';
code:=’Hl’
$liczba:=(321-1)/10=32
2 – $cyfra[2][rand(0,5)] //wylosowałem liczbę 5.
$cyfra[2][5]=’2′;
$code:=’Hl2′
$liczba:=(32-2)/10=3
3 – $cyfra[3][rand(0,5)] //wylosowałem liczbę 2.
$cyfra[3][2]=’z';
$code:=’Hl2z’;
$liczba:= (3-3)/10=0
return $code //Hl2z
KONIEC

Jak widać w naszym generatorze wykorzystaliśmy rozróżnienie wielkości liter. ‘A’!=’a’. Aby zneutralizować to przeoczenie gdybyśmy korzystali z bazy danych wykorzystamy kodowanie znaków z rozszerzeniem “_cs” (z ang. skrótu od Case Sensitive). Uwaga! Kodowanie UTF nie jest niestety w nie wyposażone (jest jedynie „_ci” -„Case Insensitive”). W tym wypadku w naszym zapytaniu SELECT dopisujemy BINARY.

$baza->query("SELECT [fields] FROM [table] WHERE id= BINARY '".$code."' LIMIT 0,1");

Przykład zastosowania prostego generatora przedstawiam tutaj.


Opcje

Info

Odpowiedz

Możesz używać tagów : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>