生成唯一编号作为图像名称

本文关键字:图像 唯一 编号 | 更新日期: 2023-09-27 17:59:53

我是asp.net c#的初学者,开始开发一个网站,现在一直停留在图像上传表单上。我必须生成一个唯一的数字作为图像的名称,并将图像存储在图像文件夹中。如何使用c#在asp.net中生成超过2位数的唯一数字。唯一数字也可以包括字母。

非常感谢您的帮助。谢谢

生成唯一编号作为图像名称

正如germi所说,唯一的4位数将限制您只能获得10000张图像。如果你事先知道你永远不会有超过10000张图像,你可以从0开始,每次增加1来获得唯一的ID。

更好的解决方案是使用Guid。Guid是全局唯一的ID。

Guid g = Guid.NewGuid();

这样,您就不必担心实现和检查文件名是否唯一,因为它们保证是.

由于我通过评论询问是否可以包含字母,而您说"可以",因此这里有一个替代您已经接受的答案的选项。生成的图像名称发生冲突的几率要小得多。如果图像名称中只有1个数字或字母(小写或大写),则奇数为1/(10+26+26)。如果图像名称中有n个数字或字母(小写或大写),则奇数会小得多。事实上它是(1/62)^n。总之,这是代码:

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

正如一些人所指出的,只需对new Random()进行一次调用,或者使其成为静态的或类似的东西,并在每次调用GenerateString()时传递它。

我建议您不要使用4位数字,因为您只能获得10000个数字。看看Guid——它旨在为您提供独特的价值。

如果数字不一定是随机的,你可以每次只增加一个计数器并跟踪它。

如果你真的打算使用0-10000之间的随机数,你可以使用这样的东西:

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;

之后,你必须检查该图像是否已经存在(或者你必须保留一个已经使用的数字列表并查看)。

如果你想使用Guids,你可以这样做:

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

Guid的设计是独一无二的,所以你在这方面不会有任何问题。

GUID是一个128位整数(16字节),可以在所有需要唯一标识符的计算机和网络中使用。这样的标识符被复制的概率非常低。

(请参阅文档)。

正如大家所说,4位数字非常小,除非在有限的用例中,否则不会特别有用。

您有几种可能的解决方案。使用Guid通常被认为是最好的解决方案,因为它适用于多台机器,您不必检查刚刚生成的Guid是否已经使用。所有其他方法都需要执行这种重复检查,这取决于名称的存储方式,可能是一件麻烦的事情。

如果正如你所说,你真的需要4位数字,而这就是你所允许的,那么随机数对你来说不是最好的。只需按顺序排列并使用关键部分。您可以在目录或数据库中查找第一次使用的最高值,然后开始递增一(您甚至可以使用Interlocked increment来增加数字)。

但是,正如其他人所说,你应该重新考虑4位数的限制。

你试过这样吗:

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

以及你将要保存的这些路径。

我现在知道这是一个旧线程,但当我说为什么不,让我们使用Datetime ticks作为其他线程的替代时,我记得我自己。若要将图像名称存储在数据库中,则必须考虑字节。因此,与guid(没有破折号)相比:

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

然后用于:

  1. tickUnique结果为:637483067615257804
  2. guidUnique结果为:72fdea88b6074595875d7a6240c390f1

最后一件事,我不得不提一下。日期时间刻度在同一线程中将始终是唯一的。在线程场景中,您必须小心谨慎。

编码快乐!

添加到此对话:

如果出于存储原因,你想保留一个真实的ID,但希望用户使用这些图像和/或以不同的方式生成文件名,你可以使用hashids.net等库。

基本上,你插入一个";盐";和一个数字,你会得到一个哈希,这个哈希可以被你的系统可逆(因为你知道salt!),但用户很难反转。这也可能有助于防止刮擦器扫描您的端点。

你的上传处理程序会看起来像这个


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