Konieczność obsługi> 1000, ale <10000 nowych rekordów dziennie
Nie można używać identyfikatorów GUID / UUID, numerów automatycznego zwiększania itp.
Idealnie powinno być 5 lub 6 znaków, oczywiście może być alfa
Chciałbym ponownie wykorzystać istniejące, dobrze znane algos, jeśli są dostępne
Coś tam jest?
Odpowiedzi:
Base 62 jest używany przez tinyurl i bit.ly dla skróconych adresów URL. Jest to dobrze znana metoda tworzenia „unikalnych”, czytelnych dla człowieka identyfikatorów. Oczywiście będziesz musiał przechowywać utworzone identyfikatory i sprawdzać duplikaty podczas tworzenia, aby zapewnić ich niepowtarzalność. (Zobacz kod na dole odpowiedzi)
Metryki niepowtarzalności Base 62
5 znaków w bazie 62 daje 62 ^ 5 unikalnych identyfikatorów = 916 132 832 (~ 1 miliard) Przy 10 tys. Identyfikatorów dziennie będzie dobrze przez ponad 91 tys. Dni
6 znaków w bazie 62 daje 62 ^ 6 unikalnych identyfikatorów = 56800235584 (ponad 56 miliardów) Przy 10 tys. Identyfikatorów dziennie będziesz w porządku przez ponad 5 milionów dni
Podstawowe wskaźniki niepowtarzalności 36
6 znaków zapewni 36 ^ 6 unikalnych identyfikatorów = 2,176,782,336 (ponad 2 miliardy)
7 znaków zapewni 36 ^ 7 unikalnych identyfikatorów = 78,364,164,096 (ponad 78 miliardów)
Kod:
public void TestRandomIdGenerator() { // create five IDs of six, base 62 characters for (int i=0; i<5; i++) Console.WriteLine(RandomIdGenerator.GetBase62(6)); // create five IDs of eight base 36 characters for (int i=0; i<5; i++) Console.WriteLine(RandomIdGenerator.GetBase36(8)); } public static class RandomIdGenerator { private static char[] _base62chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" .ToCharArray(); private static Random _random = new Random(); public static string GetBase62(int length) { var sb = new StringBuilder(length); for (int i=0; i<length; i++) sb.Append(_base62chars[_random.Next(62)]); return sb.ToString(); } public static string GetBase36(int length) { var sb = new StringBuilder(length); for (int i=0; i<length; i++) sb.Append(_base62chars[_random.Next(36)]); return sb.ToString(); } }
Wynik:
źródło
Polecam http://hashids.org/, który konwertuje dowolną liczbę (np. DB ID) na łańcuch (używając soli).
Pozwala dekodować ten ciąg z powrotem do numeru. Nie musisz więc przechowywać go w bazie danych.
Posiada biblioteki dla JavaScript, Ruby, Python, Java, Scala, PHP, Perl, Swift, Clojure, Objective-C, C, C ++ 11, Go, Erlang, Lua, Elixir, ColdFusion, Groovy, Kotlin, Nim, VBA, CoffeeScript oraz Node.js i .NET.
źródło
Miałem podobne wymagania jak OP. Sprawdziłem dostępne biblioteki, ale większość z nich opiera się na przypadkowości i tego nie chciałem. Naprawdę nie mogłem znaleźć niczego, co nie byłoby oparte na przypadkowości i wciąż było bardzo krótkie ... Więc skończyłem na swojej własnej, opartej na technice Flickr , ale zmodyfikowanej tak, aby wymagała mniejszej koordynacji i pozwalała na dłuższe okresy offline.
W skrócie:
Niedogodności:
Zalety
Opublikowałem zarówno bibliotekę Javascript po stronie klienta, jak i implementację serwera Java EE. Wdrożenie serwerów w innych językach również powinno być łatwe.
Oto projekty:
suid - Identyfikatory unikalnych usług rozproszonych, które są krótkie i przyjemne
suid-server-java - implementacja serwera Suid dla stosu technologii Java EE.
Obie biblioteki są dostępne na liberalnej licencji open source Creative Commons. Mając nadzieję, że może to pomóc komuś innemu szukającemu krótkich unikalnych identyfikatorów.
źródło
suid
?Użyłem podstawy 36, kiedy rozwiązałem ten problem dla aplikacji, którą tworzyłem kilka lat temu. Musiałem wygenerować czytelny dla człowieka, racjonalnie unikalny numer (w każdym razie w bieżącym roku kalendarzowym). Zdecydowałem się użyć czasu w milisekundach od północy 1 stycznia bieżącego roku (więc każdego roku znaczniki czasu mogą się zduplikować) i przekonwertować go na podstawową liczbę 36. Jeśli opracowywany system napotkał błąd krytyczny, generował podstawowy numer 36 (7 znaków), który był wyświetlany użytkownikowi końcowemu za pośrednictwem interfejsu internetowego, który mógł następnie przekazać napotkany problem (i numer) do pracownika pomocy technicznej (który może następnie użyć go do znalezienia punktu w dziennikach, w którym rozpoczął się ślad stosu). Liczba taka jak 56af42g7jest nieskończenie łatwiejsze do odczytania i przekazania przez użytkownika niż znacznik czasu, taki jak 2016-01-21T15: 34: 29.933-08: 00 lub losowy identyfikator UUID, taki jak 5f0d3e0c-da96-11e5-b5d2-0a1d41d68578 .
źródło
Bardzo podoba mi się prostota kodowania GUID przy użyciu formatu Base64 i obcięcia końcowego == w celu uzyskania ciągu 22 znaków (zajmuje to jedną linię kodu i zawsze można przekonwertować go z powrotem na GUID). Niestety czasami zawiera znaki + i /. OK dla bazy danych, niezbyt dobre dla adresów URL, ale pomogło mi to docenić inne odpowiedzi :-)
Z https://www.codeproject.com/Tips/1236704/Reducing-the-string-Length-of-a-Guid autorstwa Christiaana van Bergena
var newGuid = Guid.NewGuid(); var messageID = Convert.ToBase64String(newGuid.ToByteArray()); var message22chars = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Substring(0,22);
źródło