我是asp.net c#的初学者,开始开发一个现在停留在图片上传表单上的网站。我必须生成一个唯一的数字作为图像的名称,并将图像存储在images文件夹中。如何使用c#在asp.net中生成超过2位数的唯一数字。唯一号码也可以包含字母。
非常感谢任何帮助。 谢谢!
答案 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("-", "");
然后为:
最后一点,我不得不提一下。日期时间刻度将始终是唯一的在同一线程中。在线程化场景中你必须小心。
快乐编码!
答案 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.
}