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

时间:2014-04-23 13:57:06

标签: c# asp.net

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

非常感谢任何帮助。 谢谢!

7 个答案:

答案 0 :(得分:3)

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

更好的解决方案是使用Guids。 Guids是全球唯一的ID。

Guid g = Guid.NewGuid();

然后您不必担心实施并检查您的文件名是否是唯一的,因为它们可以保证。

答案 1 :(得分:0)

我建议你不要使用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字节),可以在需要唯一标识符的所有计算机和网络中使用。这样的标识符被复制的可能性非常低。

(参见documentation)。

答案 2 :(得分:0)

正如大家所说,除了有限的使用案例外,4位数字非常小,并不是特别有用。

您有几种可能的解决方案。使用Guid通常被认为是最佳解决方案,因为它可以跨机器工作,您无需检查并查看您刚刚生成的是否已经使用过。所有其他方法都需要执行此重复检查,这取决于名称的存储方式可能是一件苦差事。

如果你说的话,你确实需要4个数字,而且你只允许这样做,那么随机数就不是最适合你的。只需顺序并使用关键部分。您可以查看目录或数据库并在第一次获得最高使用值,然后开始递增1(您甚至可以使用Interlocked Increment来增加数量)。

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

答案 3 :(得分:0)

你试试这样:

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

这些路径你将保存。

答案 4 :(得分:0)

由于我通过评论询问是否可以包含字母并且您说“是”,这里可以替代您已接受的答案。生成的图像名称相互碰撞的可能性要小得多。如果图像名称中只有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);
}

有几个人已经指出,只需调用一个新的Random()或使其成为静态或类似的东西,并在每次调用GenerateString()时传递它。

答案 5 :(得分:0)

我现在认为它是一个旧线程,但我记得我自己说为什么不,让我们使用日期时间刻度作为其他任何东西的替代品。 如果要将图像名称存储在数据库中,则必须考虑字节。 所以与 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

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

快乐编码!

答案 6 :(得分:0)

要添加到此对话中:

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

基本上你插入一个“盐”和一个数字,你会得到一个可以被你的系统逆转的散列(因为你会知道盐!)但用户很难逆转。这还可以帮助您防止抓取工具通过您的端点进行扫描。

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


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