如何在nodejs中为上传的文件生成简短的唯一名称?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29605672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to generate short unique names for uploaded files in nodejs?
提问by Erik
I need to name uploaded files by short unique identifier like nYrnfYEva4vhAoFGhwX6aOr7. How could I ensure uniqueness of files?
我需要通过简短的唯一标识符命名上传的文件,如nYrnfYEva4vhAoFGhwX6aOr7. 如何确保文件的唯一性?
回答by ItalyPaleAle
(Posting my comments as answer, with responses to your concerns)
(张贴我的评论作为答案,并回应您的担忧)
You may want to check out the shortidNPM module, which generates short ids (shockingly, I know :) ) similar to the ones you were posting as example. The result is configurable, but by default it's a string between 7 and 14 characters (length is random too), all URL-friendly (A-Za-z0-9\_\-in a regex).
您可能想查看shortidNPM 模块,该模块生成的短 ID(令人震惊的是,我知道 :) )类似于您作为示例发布的那些。结果是可配置的,但默认情况下它是 7 到 14 个字符之间的字符串(长度也是随机的),所有 URL 友好(A-Za-z0-9\_\-在正则表达式中)。
To answer your (and other posters') concerns:
回答您(和其他发帖人)的疑虑:
- Unless your server has a true random number generator (highly unlikely), every solution will use a PRNG (Pseudo-Random Number Generator). shortid uses Node.js crypto module to generate PRNG numbers, however, which is a much better generator than Math.random()
- shortid's are not sequential, which makes it even harder to guess them
- While shortid's are not guaranteed to be unique, the likelihood of a collision is extremely small. Unless you generate billions of entries per year, you could safely assume that a collision will never happen.
- For most cases, relying on probability to trust that collisions won't happen is enough. If your data is too important to risk even that tiny amount, you could make the shortid basically100% unique by just prepending a timestamp to it. As an additional benefit, the file names will be harder to guess too. (Note: I wrote "basically 100% unique" because you could still, in theory, have a collision if two items are generated in the same timestamp, i.e. the same second. However, I would never be concerned of this. To have a real 100% certainty your only option is to run a check against a database or the filesystem, but that requires more resources.)
- The reason why shortid doesn't do that by itself is because for most applications the likelihood of a collision is too small to be a concern, and it's more important to have the shortest possible ids.
- 除非您的服务器具有真正的随机数生成器(极不可能),否则每个解决方案都将使用 PRNG(伪随机数生成器)。shortid 使用 Node.js 加密模块来生成 PRNG 数字,但是,这是一个比 Math.random() 更好的生成器
- shortid 不是连续的,这使得猜测它们变得更加困难
- 虽然不能保证 shortid 是唯一的,但发生冲突的可能性非常小。除非您每年生成数十亿个条目,否则您可以放心地假设碰撞永远不会发生。
- 在大多数情况下,依靠概率来相信不会发生碰撞就足够了。如果您的数据太重要而不能冒这么小的风险,您可以通过在其前面添加时间戳来使 shortid基本上100% 唯一。作为额外的好处,文件名也将更难猜测。(注意:我写了“基本上 100% 唯一”,因为从理论上讲,如果在同一时间戳(即同一秒)中生成两个项目,您仍然可能会发生冲突。但是,我永远不会担心这一点。有一个真正 100% 确定您唯一的选择是对数据库或文件系统运行检查,但这需要更多资源。)
- shortid 本身不这样做的原因是因为对于大多数应用程序来说,发生冲突的可能性太小而不必担心,而且拥有尽可能短的 id 更为重要。
回答by x80486
One option could be to generate unique identifiers (UUID) and rename the file(s) accordingly.
一种选择是生成唯一标识符 (UUID) 并相应地重命名文件。
Have a look at the kelektiv/node-uuidnpm module.
查看kelektiv/node-uuidnpm 模块。
EXAMPLE:
例子:
$ npm install uuid
...then in your JavaScript file:
...然后在您的 JavaScript 文件中:
const uuidv4 = require('uuid/v4'); // I chose v4 ? you can select others
var filename = uuidv4(); // '110ec58a-a0f2-4ac4-8393-c866d813b8d1'
Any time you execute uuidv4()you'll get a very-fresh-new-one.
任何时候你执行uuidv4()你都会得到一个非常新鲜的新的。
NOTICE:There are other choices/types of UUIDs. Read the module's documentation to familiarize with those.
注意:还有其他选择/类型的 UUID。阅读模块的文档以熟悉这些。
回答by zdszsdasd
I think you might be confused about true-random and pseudo-random.
我认为您可能对真随机和伪随机感到困惑。
Pseudo-random strings 'typically exhibit stastical randomness while being generated by an entirely deterministic casual process'. What this means is, if you are using these random values as entropy in a cryptographic application, you do not want to use a pseudo-random generator.
伪随机字符串“通常表现出统计随机性,同时由完全确定性的随机过程生成”。这意味着,如果您在加密应用程序中使用这些随机值作为熵,您不想使用伪随机生成器。
For your use, however, I believe it will be fine - just check for potential (highly unlikely) clashes.
但是,对于您的使用,我相信它会很好 - 只需检查潜在的(极不可能的)冲突。
All you are wanting to do is create a random string - not ensure it is 100% secure and completely random.
您要做的就是创建一个随机字符串 - 不能确保它是 100% 安全且完全随机的。
回答by Dineshaws
Try following snippet:-
尝试以下片段:-
function getRandomSalt() {
var milliseconds = new Date().getTime();
var timestamp = (milliseconds.toString()).substring(9, 13)
var random = ("" + Math.random()).substring(2, 8);
var random_number = timestamp+random; // string will be unique because timestamp never repeat itself
var random_string = base64_encode(random_number).substring(2, 8); // you can set size here of return string
var return_string = '';
var Exp = /((^[0-9]+[a-z]+)|(^[a-z]+[0-9]+))+[0-9a-z]+$/i;
if (random_string.match(Exp)) { //check here whether string is alphanumeric or not
return_string = random_string;
} else {
return getRandomSalt(); // call recursivley again
}
return return_string;
}
File name might have an alphanumeric name with uniqueness according to your requirement. Unique name based on the concept of timestamp of current time because current time never repeat itself in future and to make it strong i have applied a base64encodewhich will be convert it into alphanumeric.
根据您的要求,文件名可能具有具有唯一性的字母数字名称。基于当前时间时间戳概念的唯一名称,因为当前时间在未来永远不会重复并使其强大,我应用了base64encode将其转换为字母数字。
var file = req.files.profile_image;
var tmp_path = file.path;
var fileName = file.name;
var file_ext = fileName.substr((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1);
var newFileName = getRandomSalt() + '.' + file_ext;
Thanks
谢谢

