【问题标题】:Generate unique string for Lucky number [duplicate]为幸运号码生成唯一字符串[重复]
【发布时间】:2012-09-04 05:45:26
【问题描述】:

可能重复:
Unique random string generation

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

我不喜欢使用 GUID,因为它在中间是破折号(-)。 Here is an example 不过好像也太长了。

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

任何好的想法都将不胜感激。 干杯

【问题讨论】:

  • 是的,我可以这样做..但是对于这个目的来说仍然太长了。
  • “似乎太长”不是发布另一个问题的理由。
  • 这是什么东西吗? stackoverflow.com/questions/1122483/…
  • “独特性”是如何衡量的?它是否必须是唯一的一次程序运行?或者对于一台机器上的所有运行?或者对于世界上所有机器上的所有运行?需要更多背景信息!

标签: c#


【解决方案1】:
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");
        }
    }
}

【讨论】:

    【解决方案2】:

    就在昨天不得不做同样的任务。给你:

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

    【讨论】:

    • 毫米?请解释。你的意思是,它可以用更少的击键来完成?当然可以,毫无疑问。
    【解决方案3】:

    你可以试试这个:

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

    其中 EscapeNonCharAndNonDigitSymbols 是扩展方法:

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

    【讨论】:

    • 这个会给你18个字符,比如:0ULpP0HECPquj8TtGA
    【解决方案4】:

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

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

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

    【讨论】:

    • 它们当然是非常无聊的十六进制数字。而且 3.2 倍太长,更无聊。
    • 有时“无聊”是最好的解决方案。
    猜你喜欢
    • 2012-06-17
    • 2019-05-04
    • 2019-09-26
    • 2017-04-06
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多