简体   繁体   中英

Generate unique number as image name

I am a beginner with asp.net c#, started developing a website now stuck on image uploading form. I have to generate a unique number as a name of image and store the image in the images folder.How can i generate unique number of more than 2 digits in asp.net using c#. Unique number can also include letters.

Any help is highly appreciated. Thanks!

As germi said a unique number of 4 digits will limit you to only 10000 images. If you know in advance you will never have more than 10000 images you could start at 0 and increment the number by 1 each time to get a unique ID.

A better solution would be to make use of Guids. Guids are globally unique IDs.

Guid g = Guid.NewGuid();

Then you won't have to worry about the implementation and checking to see if your filenames are unique, since they are guaranteed to be.

I would suggest you don't use a 4-digit-number for this purpose as you'll only get 10000 of those. Have a look at Guid - it's designed to give you unique values.

If the numbers don't have to be random, you can just increment a counter by one each time and keep track of that.

If you're really set on using random numbers from 0-10000, you can use something like this:

Random r = new Random(); // <-- this should be only called once and not every time you want a random number
int nextRandom = r.Next(10000);
// as per the updated question, you want at least two digits
int nextRandomTwoDigits = r.Next(9990) + 10;

After this, you'll have to check if that image already exists (or you have to keep a list of already used numbers and look in there).

If you want to use Guids , you can do that like this:

Guid newGuid = Guid.NewGuid();
string imageName = newGuid.ToString();

Guid s are designed to be unique so you won't have any problem in that regard.

A GUID is a 128-bit integer (16 bytes) that can be used across all computers and networks wherever a unique identifier is required. Such an identifier has a very low probability of being duplicated.

(See the documentation ).

As everyone has said, 4 digits is insanely small and not particularly useful except in limited use cases.

You have several possible solutions. Using a Guid is generally considered the BEST solution, because it works across machines and you don't have to check and see if one you just generated has already been used. All of the other methods require this duplication check to be performed, which depending on how the names are stored can be a chore.

If as you say, you really do need 4 digits, and that's all you are allowed, then a random number is not best for you. Just go sequential and use a critical section. You can look in the directory or database and get the highest used value the first time, then start increment by one (you could even use Interlocked Increment to increase the number).

But, as everyone else has said, you should re-think the 4 digit limit.

Have you try like this :

 string filePath = Path.Combine(Server.MapPath("~/UserImages"), Path.GetFileName(Guid.NewGuid() + "_" + file.FileName));

and these path you will save.

Since I asked via a comment if letters can be included and you said 'Yes', here's an alternative to your already accepted answer. The chance for your generated image names to collide with each other is much smaller. If the image name has only 1 number or letter (lower or upper case) in it, the odd is 1/(10 + 26 + 26). If the image name has n numbers or letters (lower or upper case) in it, the odd gets much smaller. In fact it is (1/62) ^ n. (^ is to the power of). Anyway here's the code:

 public char GenerateChar(System.Random random)
 {
        char randomChar;
        int next = random.Next(0, 62);
        if (next < 10)
        {
            randomChar = (char) (next + '0'); //0, 1, 2 ... 9
        }
        else if (next < 36)
        {
            randomChar = (char) (next - 10 + 'A'); //A, B, C ... Z
        }
        else
        {
            randomChar = (char) (next - 36 + 'a'); //a, b, c ... z
        }
        return randomChar;
}

public string GenerateString(System.Random random, int length)
{
        char[] randomStr = new char[length];
        for (int i = 0; i < length; i++)
        {
            randomStr[i] = GenerateChar(random);
        }
        return new string(randomStr);
}

As several have pointed out, just make one call to new Random() or make it static or something like that, and pass it in each time you call GenerateString().

I now that it is an old thread, but i remember my self when i said why not, lets use Datetime ticks as an alternative of anything else. And if you will store the image name in database, then you have to consider bytes. So compared to guid(without dashes):

 long ticks = DateTime.Now.Ticks;
 string tickUnique = String.Format("{0}", ticks);
 string guidUnique = Guid.NewGuid().ToString();
 guidUnique = guidUnique.Replace("-", "");

Then for:

  1. tickUnique the results is: 637483067615257804
  2. guidUnique the result is: 72fdea88b6074595875d7a6240c390f1

Something last, that i have to mention. Datetime ticks will be always unique in the same thread . You must be carefull in a threaded scenario.

Happy coding!

To add into this conversation:

If you want to keep a real ID for storing reasons but wish your users to consume those images and/or have their filenames generated differently you could use a library such as hashids.net .

Basically you plug in a "salt" and a number and you get a hash that is reversible by your system (since you'll know the salt!) but hard for users to reverse. This might also help you prevent scrapers from scanning thru your endpoints.

Your upload handler would then look something like this


private readonly IHashids _hashidsSource = new Hashids("Salty salt");

async Task HandleUploadedImage(MyImage img, CancellationToken ct)
{
    // Assuming MyImage.Id is an int autogenerated by each uploaded image.
    var hashedFilename = _hashidsSource.Encode(img.Id);
    img.Filename = hashedFilename;
    // TODO: ???
    // Profit.
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM