Question

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.

Was it helpful?

Solution

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 :)

OTHER TIPS

You could generate a Guid using :

Guid.NewGuid().ToString();

It would give you something like :

788E94A0-C492-11DE-BFD4-FCE355D89593

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top