2009-09-22 21 views

Odpowiedz

38

Można użyć Base64:

string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray()); 

który generuje ciąg jak E1HKfn68Pkms5zsZsvKONw==. Ponieważ GUID ma zawsze 128 bitów, można pominąć ==, o którym wiadomo, że zawsze będzie obecny na końcu i da ci 22-znakowy ciąg znaków. To nie jest tak krótki jak YouTube.

+21

Metoda ta ma tę wadę, że wygenerowane wartości może zawierać ukośnik (/) znak, który może, gdy unproperly obchodzić, być niewygodne dla użytkownika w Url –

+2

Chociaż bardzo podoba mi się to rozwiązanie, zgadzam się z Jhonny D. nie tylko "/" może się pojawić, ale także "+", które całkowicie zepsuje twój adres URL. * westchnienie * – c0d3p03t

+2

Wystarczy zamienić znaki "/" i "+" na bezpieczne znaki URL, takie jak "-" i "_". Następnie, po ponownym wczytaniu przewodnika, należy je wymienić przed rozpoczęciem dekodowania. –

3

Technicznie to nie jest Guid. Youtube ma prosty, losowy generator ciągów, który możesz prawdopodobnie pobudzić w ciągu kilku minut, używając tablicy dozwolonych znaków i generatora liczb losowych.

1

Ten identyfikator prawdopodobnie nie jest unikalny na całym świecie. Identyfikatory GUID powinny być globalnie unikalne, ponieważ zawierają elementy, które nie powinny występować gdzie indziej (adres MAC komputera generującego identyfikator, czas wygenerowania identyfikatora itp.).

Jeśli potrzebny jest identyfikator, który jest unikalny w obrębie Twoja aplikacja, użyj fontanny liczbowej - być może kodującej wartość jako liczbę szesnastkową. Za każdym razem, gdy potrzebujesz identyfikatora, pobierz go z fontanny numerycznej.

Jeśli masz wiele serwerów przydzielających identyfikatory, możesz pobrać szereg numerów (kilka dziesiątek lub tysięcy w zależności od tego, jak szybko przydzielasz identyfikatory), które powinny wykonać zadanie. 8-cyfrowy numer szesnastkowy da ci 4 miliardy identyfikatorów - ale twój pierwszy identyfikator będzie dużo krótszy.

10

9 znaków nie jest Guid. Biorąc pod uwagę to, możesz użyć szesnastkowej reprezentacji int, która daje ci 8 ciągów znaków.

Aktualizacja 1: Nie wiem, dlaczego dostał downvote powyżej, ale dla każdego, kto się zastanawiam:

Można użyć identyfikatora może już mieć. Możesz również użyć .GetHashCode przeciwko różnym typom prostym i tam masz inne int. Możesz także xorować różne pola. A jeśli się na to zdecydujesz, możesz nawet użyć liczby losowej - hej, masz ponad 2 000 000 000+ możliwych wartości, jeśli trzymasz się pozytywów;)

+0

Zastanawiam się również, że ... w każdym przypadku, właśnie wysłałem aktualizację podając, co daje dodatkowe powody, aby zrobić odwrotnie - upvote :) – eglasius

3

To może nie być najlepsze rozwiązanie, ale możesz zrobić coś takiego:

string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0); 
+0

Jedyny problem z tą metodą jest to, że drugi argument jest faktycznie dla minimalnej liczby nie -fabetyczne i nieliczbowe. Kiedy próbuję z '0', otrzymuję kilka takich symboli ... – Azimuth

4

Jak wspominają inni, YouTube VideoId nie jest technicznie GUID ponieważ nie jest z natury wyjątkowy.

Zgodnie Wikipedia:

łączna liczba unikatowych kluczy wynosi 2 lub 3,4 x 10 . Liczba ta jest tak duża, że ​​prawdopodobieństwo, że ta sama liczba będzie generowana losowo dwa razy, jest nieistotne.

Unikalność YouTube VideoId jest obsługiwana przez ich algorytm generatora.

Możesz napisać własny algorytm lub użyć dowolnego losowego generatora napisów i użyć ograniczenia UNIQUE CONSTRAINT w SQL, aby wymusić jego wyjątkowość.

Najpierw utwórz UNIQUE CONSTRAINT w bazie danych:

ALTER TABLE MyTable 
ADD CONSTRAINT UniqueUrlId 
UNIQUE (UrlId); 

Następnie, na przykład wygenerować losowy ciąg znaków (od philipproplesch na answer):

string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0); 

Jeżeli generowany UrlId jest wystarczająco przypadkowe i Wystarczająco długo powinieneś rzadko spotykać się z wyjątkiem, który jest generowany, gdy SQL napotka duplikat UrlId. W takim przypadku możesz łatwo obsłużyć wyjątek w swojej aplikacji internetowej.

+0

Jedynym problemem z metodą' GeneratePassword' jest to, że drugi argument jest tak naprawdę dla minimalnej liczby nie alfabetycznych i nieliczbowych znaków. Kiedy próbuję z '0', otrzymuję kilka takich symboli ... – Azimuth

5

Jak wspomniano w zaakceptowanej odpowiedzi, może powodować problemy, jeśli używasz identyfikatora GUID w adresie URL. Tutaj jest bardziej kompletna odpowiedź:

public string ToShortString(Guid guid) 
    { 
     var base64Guid = Convert.ToBase64String(guid.ToByteArray()); 

     // Replace URL unfriendly characters with better ones 
     base64Guid = base64Guid.Replace('+', '-').Replace('/', '_'); 

     // Remove the trailing == 
     return base64Guid.Substring(0, base64Guid.Length - 2); 
    } 

    public Guid FromShortString(string str) 
    { 
     str = str.Replace('_', '/').Replace('-', '+'); 
     var byteArray = Convert.FromBase64String(str + "=="); 
     return new Guid(byteArray); 
    } 

Zastosowanie:

 var guid = Guid.NewGuid(); 
     var shortStr = ToShortString(guid); 
     // shortStr will look something like 2LP8GcHr-EC4D__QTizUWw 
     var guid2 = FromShortString(shortStr); 
     Assert.AreEqual(guid, guid2); 
Powiązane problemy