66

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

どのようにそれを行うことができますか?Webアプリで使いたいです。

4

8 に答える 8

72

Base64を使用できます。

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

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

于 2009-09-22T06:51:57.363 に答える
24

受け入れられた回答に記載されているように、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);
于 2016-12-01T17:39:57.137 に答える
11

9文字はGUIDではありません。その場合、intの16進表現を使用できます。これにより、8文字の文字列が得られます。

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

于 2009-09-22T07:03:43.160 に答える
9

GUIDではありません

次のように飛び込みましょう

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

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

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 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToCharArray();
    
    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

しかし、私はそれが常にユニークであることを保証することはできません。

アップデート2: URLをわかりやすくするためのShortGuidというプロジェクトもあります。これGUIDを通常のURLに変換できます。Guid

これはGuid、以下のコードとしてBase64にエンコードすることで機能します

public static string Encode(Guid guid)
{
    string encoded = Convert.ToBase64String(guid.ToByteArray());

    encoded = encoded
        .Replace("/", "_")
        .Replace("+", "-");
    return encoded.Substring(0, 22);
}

Guidそれの良いところは、再びデコードして元に戻すことができます

public static Guid Decode(string value)
{
    // avoid parsing larger strings/blobs
    if (value.Length != 22)
    {
        throw new ArgumentException("A ShortGuid must be exactly 22 characters long. Receive a character string.");
    }

    string base64 = value
        .Replace("_", "/")
        .Replace("-", "+") + "==";

    byte[] blob = Convert.FromBase64String(base64);
    var guid = new Guid(blob);

    var sanityCheck = Encode(guid);
    if (sanityCheck != value)
    {
        throw new FormatException(
            @"Invalid strict ShortGuid encoded string. The string '{value}' is valid URL-safe Base64, " +
            @"but failed a round-trip test expecting '{sanityCheck}'."
        );
    }

    return guid;
}

したがって、GUID4039124b-6153-4721-84dc-f56f5b057ac2はとしてエンコードされSxI5QFNhIUeE3PVvWwV6wg、出力は次のようになります。

ANf-MxRHHky2TptaXBxcwA
zpjp-stmVE6ZCbOjbeyzew
jk7P-XYFokmqgGguk_530A
81t6YZtkikGfLglibYkDhQ
qiM2GmqCK0e8wQvOSn-zLA
于 2019-05-24T11:00:08.070 に答える
7

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

ウィキペディアによると:

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

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

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

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

ALTER TABLE MyTable
ADD CONSTRAINT UniqueUrlId
UNIQUE (UrlId);

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

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

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

于 2011-10-19T17:49:21.287 に答える
4

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

于 2009-09-22T06:50:22.437 に答える
3

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

string shortUrl = System.Web.Security.Membership.GeneratePassword(11, 0);
于 2009-09-22T08:10:33.040 に答える
2

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

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

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

于 2009-09-22T06:55:32.440 に答える