关于c#:为Lucky number生成唯一字符串


Generate unique string for Lucky number

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Unique random string generation

我必须生成一个随机的唯一字符串。这样做的目的是在表中的每个成功条目之后生成一个幸运数字。

我不喜欢使用guid,因为它是中间的破折号(-)。这是一个例子,但它似乎太长了。

我想生成一个大约有10个字符的字符串。

任何好主意都会受到赞赏。干杯


可以创建不带破折号的guid的字符串表示形式:

1
Guid.NewGuid().ToString("N");

当然,它是32个字符,而不是10个字符。但这是一个简单而快速的解决方案。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;

namespace LinqRandomString
{
    class Program
    {
        static void Main(string[] args)
        {
            do
            {
                byte[] random = new byte[10000];

                using (var rng = RandomNumberGenerator.Create())
                    rng.GetBytes(random);


                var q = random
                            .Where(i => (i >= 65 && i <= 90) || (i >= 97 && i <= 122)) // ascii ranges - change to include symbols etc
                            .Take(10) // first 10
                            .Select(i => Convert.ToChar(i)); // convert to a character

                foreach (var c in q)
                    Console.Write(c);

            } while (Console.ReadLine() !="exit");
        }
    }
}


就在昨天不得不做同样的任务。干得好:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public static class RandomStringService
{
    //Generate new random every time used. Must sit outside of the function, as static, otherwise there would be no randomness.
    private static readonly Random Rand = new Random((int)DateTime.Now.Ticks);


    /// <summary>
    /// Create random unique string- checking against a table
    /// </summary>
    /// <returns>Random string of defined length</returns>
    public static String GenerateUniqueRandomString(int length)
    {
        //check if the string is unique in Barcode table.
        String newCode;
        do
        {
            newCode = GenerateRandomString(length);

         // and check if there is no duplicates, regenerate the code again.
        } while (_tableRepository.AllRecords.Any(l => l.UniqueString == newCode));

//In my case _tableRepository is injected via DI container and represents a proxy for
//EntityFramework context. This step is not really necessary, most of the times you can use
//method below: GenerateRandomString

        return newCode;
    }




    /// <summary>
    /// Generates the random string of given length.
    /// String consists of uppercase letters only.
    /// </summary>
    /// <param name="size">The required length of the string.</param>
    /// <returns>String</returns>
    private static string GenerateRandomString(int size)
    {
        StringBuilder builder = new StringBuilder();
        char ch;
        for (int i = 0; i < size; i++)
        {
            ch = Convert.ToChar(CreateRandomIntForString());
            builder.Append(ch);
        }
        return builder.ToString();
    }



    /// <summary>
    /// Create a random number corresponding to ASCII uppercase or a digit
    /// </summary>
    /// <returns>Integer between 48-57 or between 65-90</returns>
    private static int CreateRandomIntForString()
    {
        //ASCII codes
        //48-57 = digits
        //65-90 = Uppercase letters
        //97-122 = lowercase letters

        int i;
        do
        {
            i = Convert.ToInt32(Rand.Next(48, 90));
        } while (i > 57 && i < 65);

        return i;
    }


你可以试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public struct ShortGuid
{
    private Guid _underlyingGuid;

    public ShortGuid(Guid underlyingGuid) : this()
    {
        _underlyingGuid = underlyingGuid;
    }

    public static ShortGuid Empty
    {
        get { return ConvertGuidToShortGuid(Guid.Empty); }
    }

    public static ShortGuid NewShortGuid()
    {
        return ConvertGuidToShortGuid(Guid.NewGuid());
    }

    private static ShortGuid ConvertGuidToShortGuid(Guid guid)
    {
        return new ShortGuid(guid);
    }

    public override string ToString()
    {
        return Convert.ToBase64String(_underlyingGuid.ToByteArray()).EscapeNonCharAndNonDigitSymbols();
    }

    public bool Equals(ShortGuid other)
    {
        return other._underlyingGuid.Equals(_underlyingGuid);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (obj.GetType() != typeof (ShortGuid)) return false;
        return Equals((ShortGuid) obj);
    }

    public override int GetHashCode()
    {
        return _underlyingGuid.GetHashCode();
    }
}

其中escapenconcharandnondigitsymbols是扩展方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
    public static string EscapeNonCharAndNonDigitSymbols(this string str)
    {
        if (str == null)
            throw new NullReferenceException();
        var chars = new List<char>(str.ToCharArray());

        for (int i = str.Length-1; i>=0; i--)
        {
            if (!Char.IsLetterOrDigit(chars[i]))
                chars.RemoveAt(i);
        }
        return new String(chars.ToArray());
    }