2016-04-14 30 views
2

お客様に送信するプロモーションコードの作成を検討していますが、各コードがユニークであることが伝えられています - 5文字 - 英数字。ユニークな5文字の英数字の文字列を作成

私は、連結された文字列のハッシュを行い、ハッシュの最初の5文字を​​とると考えましたが、同じ5文字が何度も繰り返される可能性があります。

誰も私にこのユニークな5文字のアルファベット文字列を作成するためのあらゆる指針を与えることができますか?

+1

テキストファイルを作成し、それが行われたとき、それにそれぞれのコードを追加し、その後、毎回1は、あなたがどこか既存を格納する必要が –

+0

ファイルにない独自の1までキープそれらを生成作られてすべてを使って作成したすべてのファイルを比較してください – fubo

+0

これは非常にクリーンなソリューションAlfieのようには聞こえませんが、これは一意性を保つためにループするのに非常に長い時間がかかり、ファイルは送信されるコードごとに大きくなります。 –

答えて

4

私の他の答えのコメントで述べたように、あなたの目的には十分ではないかもしれません。私はランダムな英数字の文字列を生成するいくつかのコードを作成しました。今回は、0-9およびA-Fに限定されず、すなわち、ランダムに生成されたnibblesの16進数と等価である。代わりに、英数字の大文字、少なくとも大文字で構成されています。これは16進数の可能な16文字からフルアルファベットと0-9までの可能な36文字になるので、一意性の可能性を十分に高めるはずです。

それでも、私が10,000,000回の試行でそれを実行したとき、十分なダブがありました。それは獣の本質だけです。あなたがそのような短い文字列でdupを取得する可能性はかなり高いです。とにかく、ここにあります。あなたはそれで周りを遊ぶことができます。クライアントが小文字を気にしない場合(例: 「RORYAP」と「RoryAp」が異なる場合は、一意性の可能性がさらに高まります。

/// <summary> 
/// Instances of this class are used to geneate alpha-numeric strings. 
/// </summary> 
public sealed class AlphaNumericStringGenerator 
{ 
    /// <summary> 
    /// The synchronization lock. 
    /// </summary> 
    private object _lock = new object(); 

    /// <summary> 
    /// The cryptographically-strong random number generator. 
    /// </summary> 
    private RNGCryptoServiceProvider _crypto = new RNGCryptoServiceProvider(); 

    /// <summary> 
    /// Construct a new instance of this class. 
    /// </summary> 
    public AlphaNumericStringGenerator() 
    { 
     //Nothing to do here. 
    } 

    /// <summary> 
    /// Return a string of the provided length comprised of only uppercase alpha-numeric characters each of which are 
    /// selected randomly. 
    /// </summary> 
    /// <param name="ofLength">The length of the string which will be returned.</param> 
    /// <returns>Return a string of the provided length comprised of only uppercase alpha-numeric characters each of which are 
    /// selected randomly.</returns> 
    public string GetRandomUppercaseAlphaNumericValue(int ofLength) 
    { 
     lock (_lock) 
     { 
      var builder = new StringBuilder(); 

      for (int i = 1; i <= ofLength; i++) 
      { 
       builder.Append(GetRandomUppercaseAphanumericCharacter()); 
      } 

      return builder.ToString(); 
     } 
    } 

    /// <summary> 
    /// Return a randomly-generated uppercase alpha-numeric character (A-Z or 0-9). 
    /// </summary> 
    /// <returns>Return a randomly-generated uppercase alpha-numeric character (A-Z or 0-9).</returns> 
    private char GetRandomUppercaseAphanumericCharacter() 
    { 
      var possibleAlphaNumericValues = 
       new char[]{'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','0','1','2','3','4','5','6','7','8','9'}; 

      return possibleAlphaNumericValues[GetRandomInteger(0, possibleAlphaNumericValues.Length - 1)]; 
    } 

    /// <summary> 
    /// Return a random integer between a lower bound and an upper bound. 
    /// </summary> 
    /// <param name="lowerBound">The lower-bound of the random integer that will be returned.</param> 
    /// <param name="upperBound">The upper-bound of the random integer that will be returned.</param> 
    /// <returns> Return a random integer between a lower bound and an upper bound.</returns> 
    private int GetRandomInteger(int lowerBound, int upperBound) 
    { 
     uint scale = uint.MaxValue; 

     // we never want the value to exceed the maximum for a uint, 
     // so loop this until something less than max is found. 
     while (scale == uint.MaxValue) 
     { 
      byte[] fourBytes = new byte[4]; 
      _crypto.GetBytes(fourBytes); // Get four random bytes. 
      scale = BitConverter.ToUInt32(fourBytes, 0); // Convert that into an uint. 
     } 

     var scaledPercentageOfMax = (scale/(double) uint.MaxValue); // get a value which is the percentage value where scale lies between a uint's min (0) and max value. 
     var range = upperBound - lowerBound; 
     var scaledRange = range * scaledPercentageOfMax; // scale the range based on the percentage value 
     return (int) (lowerBound + scaledRange); 
    } 
} 
2

私はあなたが探しているものに役立つかもしれないこの時を思い出しました。

/// <summary> 
/// Return a string of random hexadecimal values which is 6 characters long and relatively unique. 
/// </summary> 
/// <returns></returns> 
/// <remarks>In testing, result was unique for at least 10,000,000 values obtained in a loop.</remarks> 
public static string GetShortID() 
{ 
    var crypto = new System.Security.Cryptography.RNGCryptoServiceProvider(); 
    var bytes = new byte[5]; 
    crypto.GetBytes(bytes); // get an array of random bytes.  
    return BitConverter.ToString(bytes).Replace("-", string.Empty); // convert array to hex values. 
} 

私はあなたの要件が「必須」であることを理解していますが、一意性はせいぜい相対的な概念です。でも、私たちの古い友人the GUIDは、本当にユニークではありません。

...同じ数の確率が二倍 は私が正しくリコール、私は私のコードのwasnを見つけ

ごくわずかであるランダムに生成されています多くの反復(数十万回、おそらく低百万回 - 私は正確には思い出せません)に5文字で100%ユニークですが、6でテストした結果、は少なくとも10,000,000の値でユニークなでしたループで。

長さ5で自分でテストし、目的に応じて十分にユニークであるかどうかを判断できます。必要に応じて、65に切り替えてください。

補足:他の人の中には、スレッドの安全性を考慮する必要があるかもしれないことを覚えている人がいます。

private static object _lock = new object(); 

/// <summary> 
/// Return a string of random hexadecimal values which is 6 characters long and relatively unique. 
/// </summary> 
/// <returns></returns> 
/// <remarks>In testing, result was unique for at least 10,000,000 values obtained in a loop.</remarks> 
public static string GetShortID() 
{ 
    lock(_lock) 
    { 
     var crypto = new System.Security.Cryptography.RNGCryptoServiceProvider(); 
     var bytes = new byte[5]; 
     crypto.GetBytes(bytes); // get an array of random bytes.  
     return BitConverter.ToString(bytes).Replace("-", string.Empty); // convert array to hex values. 
    } 
} 
+0

OPは "HAS TO BE UNIQUE"と非常に明確に言います。 –

+0

ありがとうございました@roryap。私は、ループやデータベース呼び出しの負荷を必要としないコードベースのソリューションを探していました。しかし、はい、私は毎回一意性を保証する必要がある、または運動が無意味である必要があります –

+0

@VictorSandそれはユニークです....それは私が答えた理由です。 –

0

可能なすべての5桁の文字列でテーブル(プロモコード)を作成します。次に、2つのフィールドを持つ別のテーブルCampaignPromoCodeを作成します。

Code varchar(5), CampaignId uniqueidentifier 

この方法では、キャンペーンごとに使用されたものを追跡できます。この文ランダム未使用promocodeの使用を取得するには:ここ

select top 1 Code 
from PromoCode pc 
    left join CampaignPromoCode cpc on cpc.Code = pc.Code 
where cpc.CampaignId = 'campaign-id-goes-here' 
    and cpc.Code is null 
order by newid() 
+0

2人の別個のユーザーが同時にそのテーブルにアクセスしても、同じコードで戻ってくることがあります。 –

+0

はい、一度に1人のユーザーしか使用できないようにシングルトンとしてメソッドを記述することができます。 – Scottie

+0

@ Richard.Gale:同時アクセスを防ぐことができます。より大きな問題は、このテーブルが60,000,000を超えるレコードでうまく動作する必要があることです。 –

0

にボトムラインは、あなたはおそらく戻っ管理に行くとユニークな絶対に100%を強制するための要件は非常にコストが法外要求であり、あなたということを伝えなければならないことです費用のほんの一部で99.9999%のユニークさを得ることができます。次に、roryapのコードを使用して、ランダムでほとんど一意のコードを生成します。

関連する問題