Krótsze skróty dzięki base64

Skróty wiadomości (ang. message digest, hash) to chleb powszedni w programowaniu. Przez funkcje md5(), sha1() itp. generowane są identyfikatory sesji, ciasteczka identyfikujące użytkownika, nazwy plików i tuzin innych rzeczy.

Skrót, jak sama nazwa wskazuje, powinien być krótki. Tymczasem w większości wypadków, z którymi się zetknąłem, skróty używane są w zapisie szesnastkowym, co oznacza, że 128 bitowy skrót MD5 jest zapisywany w 32 bajtach (czyli 256 bitach), a 160 bitowy SHA1 potrzebuje 40 znaków (256 bitów). To, delikatnie mówiąc, trąci rozrzutnością. Oszczędzić bajty można wykorzystując zapis base64, co pokazuje poniższy przykład:

var_dump(sha1('Ala ma kota')); 
var_dump(strtr(rtrim(base64_encode(sha1('Ala ma kota', true)), '='), '+/', '-_'));

Wynik:

string(40) "43fd70009a97a7d311c5644047ccc700f8d08a9d" 
string(27) "Q_1wAJqXp9MRxWRAR8zHAPjQip0"


Jak widać na powyższym przykładzie, w wypadku skrótu SHA1 oszczędność wynosi 13 bajtów czyli blisko 1/3. Gdyby było to ciasteczko to każde zapytanie HTTP do serwera wysyłane przez klienta byłoby krótsze o te 13 bajtów. Gdyby było to pole w bazie danych to na każdym wierszu oszczędność wynosiła by te 13 bajtów, a na dodatek wyszukiwanie wartości w tej kolumnie byłoby ciut szybsze. Potencjalne korzyści można by wymieniać dalej, a jeśli przemnożyć je przez setki użytkowników i tysiące odsłon to gra jest warta świeczki.

Tytułem wyjaśnienia: algorytm base64 zaokrągla wynik do wielokrotności 4 bajtów, brakujące dane uzupełnia znakami równości. Nie są one do niczego potrzebne, więc użyłem rtrim() do pozbycia się ewentualnych znaków równości na końcu. Z kolei strtr() zamienia znaki + i / które mają specjalne znaczenie w URL-ach i nazwach plików na odpowiednio - i _. Ten zabieg jest wymagany tylko jeśli skrót będzie wykorzystywany w URL-u albo nazwie pliku.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *