Więcej
Jak wygenerować losowy ciąg alfa-numeryczny?
I've been looking for a simple Java algorithm to generate a pseudo-random alpha-numeric string. W mojej sytuacji byłby on używany jako unikalny identyfikator sesji / klucza, który "prawdopodobnie" byłby unikalny w ciągu 500K+
generacji (moje potrzeby nie'wymagają niczego bardziej wyrafinowanego).
Idealnie byłoby, gdybym mógł określić długość w zależności od moich potrzeb unikalności. Na przykład, wygenerowany ciąg o długości 12 może wyglądać coś jak "AEYGF7K0DM1X"
.
1671
3
Algorytm
Aby wygenerować losowy ciąg znaków, konkatenuj znaki losowo wybrane z zestawu dopuszczalnych symboli, aż ciąg osiągnie pożądaną długość.
Implementacja
Poniżej znajduje się dość prosty i bardzo elastyczny kod do generowania losowych identyfikatorów. Przeczytaj poniższe informacje, aby zapoznać się z ważnymi uwagami dotyczącymi zastosowania.
Przykłady użycia
Utwórz niezabezpieczony generator dla 8-znakowych identyfikatorów:
Utwórz bezpieczny generator dla identyfikatorów sesji:
Utwórz generator z łatwymi do odczytania kodami do drukowania. Ciągi są dłuższe niż pełne ciągi alfanumeryczne, aby zrekompensować użycie mniejszej ilości symboli:
Użyj jako identyfikatorów sesji
Generowanie identyfikatorów sesji, które prawdopodobnie będą unikalne, nie jest wystarczająco dobre, lub możesz po prostu użyć prostego licznika. Atakujący porywają sesje, gdy używane są przewidywalne identyfikatory.
Istnieje napięcie pomiędzy długością a bezpieczeństwem. Krótsze identyfikatory są łatwiejsze do odgadnięcia, ponieważ jest mniej możliwości. Ale dłuższe identyfikatory zużywają więcej pamięci i pasma. Większy zestaw symboli pomaga, ale może powodować problemy z kodowaniem, jeśli identyfikatory są zawarte w adresach URL lub wpisywane ręcznie.
Podstawowym źródłem losowości, czyli entropii, dla identyfikatorów sesji powinien być generator liczb losowych przeznaczony do kryptografii. Jednak inicjalizacja tych generatorów może być czasami kosztowna obliczeniowo lub powolna, więc należy dołożyć starań, aby ponownie je wykorzystać, gdy jest to możliwe.
Użycie jako identyfikatorów obiektów
Nie każda aplikacja wymaga bezpieczeństwa. Losowe przydzielanie może być efektywnym sposobem dla wielu podmiotów do generowania identyfikatorów we wspólnej przestrzeni bez koordynacji lub podziału. Koordynacja może być powolna, szczególnie w środowisku klastrowym lub rozproszonym, a podział przestrzeni powoduje problemy, gdy podmioty kończą z udziałami, które są zbyt małe lub zbyt duże.
Identyfikatory generowane bez podjęcia środków, aby uczynić je nieprzewidywalnymi powinny być chronione innymi środkami, jeśli atakujący może być w stanie je przeglądać i nimi manipulować, jak to się dzieje w większości aplikacji internetowych. Powinien istnieć oddzielny system autoryzacji, który chroni obiekty, których identyfikator może być odgadnięty przez atakującego bez pozwolenia na dostęp.
Należy również zadbać o to, aby używać identyfikatorów, które są wystarczająco długie, aby kolizje były mało prawdopodobne, biorąc pod uwagę przewidywaną całkowitą liczbę identyfikatorów. Prawdopodobieństwo kolizji,]1 p, wynosi w przybliżeniu n2/(2qx), gdzie n to liczba faktycznie wygenerowanych identyfikatorów, q to liczba różnych symboli w alfabecie, a x to długość identyfikatorów. Powinna to być bardzo mała liczba, jak 2‑50 lub mniej.
Z powyższego wynika, że szansa na kolizję wśród 500k 15-znakowych identyfikatorów wynosi około 2‑52, co jest prawdopodobnie mniej prawdopodobne niż niewykryte błędy spowodowane promieniami kosmicznymi, itp.
Porównanie z identyfikatorami UUID
Zgodnie z ich specyfikacją, UUID nie są zaprojektowane do bycia nieprzewidywalnymi i nie powinny być używane jako identyfikatory sesji.
UUID w swoim standardowym formacie zajmują dużo miejsca: 36 znaków na tylko 122 bity entropii. (Nie wszystkie bity "random" UUID są wybierane losowo.) Losowo wybrany ciąg alfanumeryczny mieści więcej entropii w zaledwie 21 znakach.
UUID nie są elastyczne; mają znormalizowaną strukturę i układ. Jest to ich główna zaleta, jak również główna słabość. W przypadku współpracy z podmiotami zewnętrznymi, standaryzacja oferowana przez UUID może być pomocna. Do użytku czysto wewnętrznego, mogą być nieefektywne.
Java dostarcza sposób na zrobienie tego bezpośrednio. Jeśli nie chcesz myślników, można je łatwo usunąć. Wystarczy użyć
uuid.replace("-", "")
.Output:
Tutaj jest to w Javie:
Oto przykładowy przebieg: