web-dev-qa-db-ja.com

YouTubeのようなGUID

YouTube(N7Et6c9nL9w)のように短いGUIDを生成することは可能ですか?)

どうすればできますか? Webアプリで使いたい。

42
kusanagi

あなたはBase64を使うことができます:

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

これにより、E1HKfn68Pkms5zsZsvKONw==のような文字列が生成されます。 GUIDは常に128ビットであるため、最後に常に存在し、22文字の文字列を提供することがわかっている==を省略できます。これはYouTubeと同じくらい短いです。

48
bobbymcr

9文字はGuidではありません。それを前提として、intの16進数表現を使用すると、8文字の文字列が得られます。

pdate 1: Dunnoはなぜ上記が反対票を投じたのか、と思っている人にとっては:

すでにお持ちのIDを使用できます。また、さまざまな単純型に対して.GetHashCodeを使用でき、そこには別のintがあります。異なるフィールドをxorすることもできます。そして、あなたがそれに夢中なら、あなたは乱数を使うかもしれません-ねえ、あなたがポジティブに固執するならば、あなたは2.000.000.000+をはるかに超える可能な値を持っています;)

11
eglasius

受け入れられた回答で述べたように、URLでGUIDを使用している場合、問題が発生する可能性があります。より完全な回答を次に示します。

    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);
    }

使用法:

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

他の人が言及したように、YouTubeのVideoIdは本質的に一意ではないため、技術的にはGUIDではありません。

Wikipedia に従って:

一意のキーの総数は2です128 または3.4×1038。この数は非常に大きいため、同じ数がランダムに2回生成される確率は無視できます。

YouTubeのVideoIdの独自性は、ジェネレーターアルゴリズムによって維持されます。

独自のアルゴリズムを作成するか、何らかのランダム文字列ジェネレータを使用してSQLのUNIQUE CONSTRAINT制約を利用し、その一意性を適用できます。

まず、データベースにUNIQUE CONSTRAINTを作成します。

ALTER TABLE MyTable
ADD CONSTRAINT UniqueUrlId
UNIQUE (UrlId);

次に、たとえば、ランダムな文字列を生成します(philippropleschの answer から):

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

生成されたUrlIdが十分にランダムで十分に長い場合、SQLが重複するUrlIdを検出したときにスローされる例外はほとんど発生しません。このようなイベントでは、Webアプリで簡単に例外を処理できます。

4
Chad Levy

それは最善の解決策ではないかもしれませんが、あなたはそのようなことをすることができます:

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

技術的にはGuidではありません。 Youtubeには、許可された文字の配列と乱数ジェネレーターを使用して数分で作成できる単純なランダム化された文字列ジェネレーターがあります。

3
Scott Muc

このIDはおそらくグローバルに一意ではありません。 GUIDは、他の場所では発生しないはずの要素(IDを生成するマシンのMACアドレス、IDが生成された時間など)を含むため、グローバルに一意である必要があります。

アプリケーション内で一意のIDが必要な場合は、数値ファウンテンを使用します。おそらく値を16進数としてエンコードします。 IDが必要になるたびに、番号の泉からそれをつかみます。

IDを割り当てるサーバーが複数ある場合は、一連の数値(IDを割り当てる速さによって数十または数千)を取得でき、それでうまくいくはずです。 8桁の16進数では40億のIDが得られますが、最初のIDははるかに短くなります。

2
Robert Christie

GUIDではありません

次のようにしてみましょう

TotalMillisecondsEpochと有効な文字のセットを使用します。

これはグローバルに一意ではありませんが、定義されているインスタンスに一意です。

public string YoutubeLikeId()
{
    Thread.Sleep(1);//make everything unique while looping
    long ticks = (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1,0,0,0,0))).TotalMilliseconds;//Epoch
    char[] baseChars = new char[] { '0','1','2','3','4','5','6','7','8','9',
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
            'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x'};

    int i = 32;
    char[] buffer = new char[i];
    int targetBase= baseChars.Length;

    do
    {
        buffer[--i] = baseChars[ticks % targetBase];
        ticks = ticks / targetBase;
    }
    while (ticks > 0);

    char[] result = new char[32 - i];
    Array.Copy(buffer, i, result, 0, 32 - i);

    return new string(result);
}

出力は次のようになります

XOTgBsu
XOTgBtB
XOTgBtR
XOTgBtg
XOTgBtw
XOTgBuE

更新:Guidから同じことを達成できます。

var guid = Guid.NewGuid(); 
guid.ToString("N");
guid.ToString("N").Substring(0,8);
guid.ToString("N").Substring(8,4);
guid.ToString("N").Substring(12,4);
guid.ToString("N").Substring(16,4);
guid.ToString("N").Substring(20,12);

Guid ecd65132-ab5a-4587-87b8-b875e2fe0f35の場合、ecd65132ab5a458787b8b875e2fe0f35としてチャンクに分割されます。

しかし、それが常に一意であるとは保証できません。

Update 2:ShortGuid というプロジェクトもあり、URLに適したGUIDに変換できますfron /通常のGuid

1
Vinod Srivastav