用于对象的C#随机码字段生成器

时间:2009-10-29 13:47:48

标签: c# random uniqueidentifier seeding

我有一个具有以下属性的对象


GID
ID
代码
名称

有些客户不想输入代码,所以最初的计划是将ID放在代码中,但是orm的基础对象是不同的,所以我就像搞砸了......

我的计划是在代码中放置#### - ####完全随机的值我怎样才能生成类似于说Windows 7串行生成器类型的东西但是没有开销你会在这里做什么情况下。

3 个答案:

答案 0 :(得分:3)

您想要随机值还是唯一值?

随机!=唯一

请记住,随机仅仅表示生成相同值的概率,或者再次生成相同值的概率。随着时间的增加,产生先前值的可能性增加 - 变得接近确定。你需要哪个?

就我个人而言,我建议只使用带有某些背景的Guid [请参阅下面的最简单部分]。我还提供了一些其他建议,以便您根据自己的情况选择。


<强>最简单

如果Code是一个无界字符串[即可以是任意长度],那么生成唯一代码的最简单的半清晰方法将是

OrmObject ormObject= new OrmObject ();
string code = string.
    Format ("{0} [{1}]", ormObject.Name, Guid.NewGuid ()).
    Trim ();
// generates something like
// "My Product [DA9190E1-7FC6-49d6-9EA5-589BBE6E005E]"

您可以将ormObject.Name替换为任何可区分的字符串。我通常会使用typeof (objectInstance.GetType ()).Name,但只有在OrmObject是基类时才会起作用,如果它是用于所有内容的具体类,它们都会以类似的标签结束。重点是添加一些用户上下文,例如@Yuriy Faktorovich引用的wtf article - 用户有某些来阅读。


<强>随机

我在一两天前就随机数生成做出了回应。与构建围绕生成器的简单灵活框架生成数字不同,以提高代码和数据的质量this should help streamline your source

如果您阅读了该内容,则可以轻松编写扩展方法,例如

public static class IRandomExtensions
{
    public static CodeType GetCode (this IRandom random)
    {
        // 1. get as many random bytes as required
        // 2. transform bytes into a 'Code'
        // 3. bob's your uncle
        ...
    }
}

    // elsewhere in code
    ...
    OrmObject ormObject = new OrmObject ();
    ormObject.Code = random.GetCode ();
    ...

要实际生成值,我建议使用IRandom实现实现System.Security.Cryptography.RNGCryptoServiceProvider接口。所述实现将生成X个随机字节的缓冲区,并根据需要执行多个数据包,在耗尽时重新生成流。

此外 - 我不知道为什么我继续写作,我想这个问题真的很吸引人! - 如果CodeType是字符串并且你想要一些可读的东西,你可以通过Base64转换将所述随机字节转换为“看似”可读的字符串

public static class IRandomExtensions
{
    // assuming 'CodeType' is in fact a string
    public static string GetCode (this IRandom random)
    {
        // 1. get as many random bytes as required
        byte[] randomBytes; // fill from random
        // 2. transform bytes into a 'Code'
        string randomBase64String = 
            System.Convert.ToBase64String (randomBytes).Trim ("=");
        // 3. bob's your uncle
        ...
    }
}

记住

随机!=唯一

您的值重复。最终


唯一

您需要问自己一些关于问题的问题。

  1. 所有Code值都必须是唯一的吗? [如果没有,你的努力太难了]
  2. 什么类型是Code? [if if-length string,使用完整的Guid]
  3. 这是分布式应用程序吗? [如果不是,请使用上面@LBushkin建议的DB值]
  4. 如果是分布式应用程序,客户端应用程序是否可以生成并提交这些对象的实例? [如果是这样,那么你想要一个全球唯一的标识符,再次Guids是一个肯定的赌注]
  5. 我确信你有更多限制,但这是你遇到像你自己这样的问题时需要执行的那种查询的一个例子。从这些问题中,您将提出一系列约束。这些限制将为您的设计提供信息。

    希望这会有所帮助:)

    顺便说一句,如果您发布有关问题的更多详细信息[即约束],您将获得更高质量的解决方案。同样,什么类型是Code,是否有长度限制?格式限制?字符限制?

    Arg,最后编辑,我发誓。如果你最终使用Guids,你可能希望对它进行模糊处理,甚至通过在base64中对它们进行编码来“压缩”它们的表示 - 类似于随机数字的上面的base64转换。

    public static class GuidExtensions
    {
        public static string ToBase64String (this Guid id)
        {
            return System.Convert.
                ToBase64String (id.ToByteArray ()).
                Trim ("=");
        }
    }
    

    与截断不同,base64转换是一种有损转换。当然,上面的修剪在完全base64扩展的上下文中是有损的 - 但=只是填充,通过转换引入的额外信息,而不是原始Guid数据的一部分。如果你想从这个base64转换值返回到Guid,那么你将不得不重新填充你的base64字符串,直到它的长度是4的倍数 - 不要问,只要查找base64如果你有兴趣:)

答案 1 :(得分:1)

您可以使用以下方式生成Guid:

Guid.NewGuid().ToString();

它会给你类似的东西:

  

788E94A0-C492-11DE-BFD4-FCE355D89593

答案 2 :(得分:0)

使用数据库中的Autonumber列或Sequencer生成唯一的代码编号。几乎所有现代数据库都支持以一种或另一种形式自动生成的数字。查看数据库支持的内容。

来自DB的自动编号/音序器值保证是唯一的并且获取起来相对便宜。如果要避免分配给代码的完全顺序编号,可以将多个顺控程序值填充并连接在一起。