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

发布于 2024-08-09 22:15:54 字数 217 浏览 3 评论 0原文

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


GID
身份证号码
代码
Name

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

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

I have an object with the following properties

GID

ID

Code

Name

Some of the clients dont want to enter the Code so the intial plan was to put the ID in the code but the baseobject of the orm is different so I'm like screwed...

my plan was to put ####-#### totally random values in code how can I generate something like that say a windows 7 serial generator type stuff but would that not have an overhead what would you do in this case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

王权女流氓 2024-08-16 22:15:54

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

随机!=唯一

请记住,随机仅表示生成相同值的概率,或再次生成相同值的概率。随着时间的增加,生成先前值的可能性也会增加 - 几乎可以确定。您需要哪一个?

就我个人而言,我建议仅使用具有某些上下文的 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 文章 - 用户有一些东西要读。


随机

我一两天前回复过有关随机数生成的问题。与其说是生成数字,不如说围绕生成器构建一个简单灵活的框架来提高代码和数据的质量,这应该有助于简化您的来源

如果您阅读了该内容,您可以轻松编写一个扩展方法,比如说

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

要实际生成一个值,我建议使用 System.Security.Cryptography.RNGCryptoServiceProvider 实现一个 IRandom 接口执行。所述实现将生成 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 是什么类型? [如果是任意长度的字符串,则使用完整的 Guid]
  3. 这是一个分布式应用程序吗? [如果没有,请使用上面@LBushkin建议的DB值]
  4. 如果是分布式应用程序,客户端应用程序可以生成并提交这些对象的实例吗? [如果是这样,那么您需要一个全局唯一标识符,并且指南是肯定的选择]

我确信您有更多限制,但这是遇到问题时需要执行的查询行的示例就像你自己的一样。从这些问题中,你会得出一系列的约束。这些约束将为您的设计提供信息。

希望这会有所帮助:)

顺便说一句,如果您发布有关您的问题的更多详细信息[即约束],您将获得更好质量的解决方案。再说一遍,Code是什么Type,有长度限制吗?格式限制?性格限制?

Arg,最后一次编辑,我发誓。如果您最终确实使用了 Guid,您可能希望对其进行混淆,甚至通过将其编码为 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:)

Do you want a random value, or a unique value?

random != unique.

Remember, random merely states a probability of not generating the same value, or a probability of generating the same value again. As time increases, likelihood of generating a previous value increases - becoming a near certainty. Which do you require?

Personally, I recommend just using a Guid with some context [refer to easiest section below]. I also provided some other suggestions so you have options, depending on your situation.


easiest

If Code is an unbounded string [ie can be of any length], easiest semi-legible means of generating a unique code would be

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]"

you can substitute ormObject.Name for any distinguishable string. I would typically use typeof (objectInstance.GetType ()).Name but that will only work if OrmObject is a base class, if it's a concrete class used for everything they will all end up with similar tags. The point is to add some user context, such that - as in @Yuriy Faktorovich's referenced wtf article - users have something to read.


random

I responded a day or two ago about random number generation. Not so much generating numbers as building a simple flexible framework around a generator to improve quality of code and data, this should help streamline your source.

If you read that, you could easily write an extension method, say

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

To actually generate a value, I would suggest implementing an IRandom interface with a System.Security.Cryptography.RNGCryptoServiceProvider implementation. Said implementation would generate a buffer of X random bytes, and dole out as many as required, regenerating a stream when exhausted.

Furthermore - I don't know why I keep writing, I guess this problem is really quite fascinating! - if CodeType is string and you want something readable, you could just take said random bytes and turn them into a "seemingly" readable string via Base64 conversion

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

Remember

random != unique.

Your values will repeat. Eventually.


unique

There are a number of questions you need to ask yourself about your problem.

  1. Must all Code values be unique? [if not, you're trying too hard]
  2. What Type is Code? [if any-length string, use a full Guid]
  3. Is this a distributed application? [if not, use a DB value as suggested by @LBushkin above]
  4. If it is a distributed application, can client applications generate and submit instances of these objects? [if so, then you want a globally unique identifier, and again Guids are a sure bet]

I'm sure you have more constraints, but this is an example of the kind of line of inquiry you need to perform when you encounter a problem like your own. From these questions, you will come up with a series of constraints. These constraints will inform your design.

Hope this helps :)

Btw, you will receive better quality solutions if you post more details [ie constraints] about your problem. Again, what Type is Code, are there length constraints? Format constraints? Character constraints?

Arg, last edit, I swear. If you do end up using Guids, you may wish to obfuscate this, or even "compress" their representation by encoding them in base64 - similar to base64 conversion above for random numbers.

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

Unlike truncating, base64 conversion is not a lossful transformation. Of course, the trim above is lossful in context of full base64 expansion - but = is just padding, extra information introduced by the conversion, and not part of original Guid data. If you want to go back to a Guid from this base64 converted value, then you will have to re-pad your base64 string until its length is a multiple of 4 - don't ask, just look up base64 if you are interested :)

别靠近我心 2024-08-16 22:15:54

您可以使用以下命令生成 Guid:

Guid.NewGuid().ToString();

它会给您类似的内容:

788E94A0-C492-11DE-BFD4-FCE355D89593

You could generate a Guid using :

Guid.NewGuid().ToString();

It would give you something like :

788E94A0-C492-11DE-BFD4-FCE355D89593

拥醉 2024-08-16 22:15:54

使用数据库中的自动编号列或排序器生成唯一的代码编号。几乎所有现代数据库都支持以一种或另一种形式自动生成数字。查看您的数据库支持什么。

来自数据库的自动编号/排序器值保证是唯一的,并且获取起来相对便宜。如果您想避免为代码分配完全连续的数字,您可以将多个定序器值填充并连接在一起。

Use an Autonumber column or Sequencer from your database to generate a unique code number. Almost all modern databases support automatically generated numbers in one form or another. Look into what you database supports.

Autonumber/Sequencer values from the DB are guaranteed to be unique and are relatively inexpensive to acquire. If you want to avoid completely sequential numbers assigned to codes, you can pad and concatenate several sequencer values together.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文