如何为nodejs中的上传文件生成简短的唯一名称?

时间:2015-04-13 12:44:05

标签: node.js file-upload uniqueidentifier

我需要通过nYrnfYEv a4vhAoFG hwX6aOr7这样的简短唯一标识来命名上传的文件。我怎样才能确保文件的唯一性?

5 个答案:

答案 0 :(得分:16)

(发表我的评论作为答案,回答您的疑虑)

您可能需要查看shortid NPM模块,该模块生成短ID(令人震惊,我知道:))类似于您发布的示例。结果是可配置的,但默认情况下它是一个7到14个字符之间的字符串(长度也是随机的),所有URL友好(正则表达式中为A-Za-z0-9\_\-)。

回答您(以及其他海报')的疑虑:

  • 除非您的服务器具有真正的随机数生成器(极不可能),否则每个解决方案都将使用PRNG(伪随机数生成器)。 shortid使用Node.js加密模块生成PRNG数,但是,这是一个比Math.random()更好的生成器
  • 短片不是连续的,这使得猜测它们更加困难
  • 虽然不保证shortid是唯一的,但碰撞的可能性非常小。除非您每年生成数十亿条目,否则您可以放心地认为不会发生碰撞。
  • 在大多数情况下,依靠概率来相信碰撞不会发生就足够了。如果您的数据太重要而且风险很小,那么您可以通过在其前面添加时间戳来使短信基本 100%唯一。作为额外的好处,文件名也将更难猜测。 (注意:我写了"基本上是100%唯一"因为如果在同一个时间戳中生成两个项目,即同一秒,你仍然可能会发生冲突。但是,我永远不会担心要真正100%确定,你唯一的选择就是对数据库或文件系统进行检查,但这需要更多的资源。)
  • 为什么shortid本身不这样做是因为对于大多数应用来说,碰撞的可能性太小而不能成为一个问题,并且拥有尽可能短的ID更重要。< / LI>

答案 1 :(得分:13)

一个选项可能是生成唯一标识符(UUID)并相应地重命名文件。

查看kelektiv/node-uuid npm模块。


示例:

$ npm install uuid

...然后在您的JavaScript文件中:

const uuidv4 = require('uuid/v4'); // I chose v4 ‒ you can select others
var filename = uuidv4(); // '110ec58a-a0f2-4ac4-8393-c866d813b8d1'

每当您执行uuidv4()时,您都会获得非常新鲜的

  

注意:还有其他选择/类型的UUID。阅读模块的文档以熟悉这些文档。

答案 2 :(得分:2)

非常简单的代码。产生一个几乎唯一的文件名 或者如果这还不够,您检查文件是否存在

function getRandomFileName() {
var timestamp = new Date().toISOString().replace(/[-:.]/g,"");  
var random = ("" + Math.random()).substring(2, 8); 
var random_number = timestamp+random;  
return random_number;
}

答案 3 :(得分:-2)

我认为你可能会对真随机和伪随机感到困惑。

伪随机字符串'通常表现出绝对随机性,同时由完全确定的临时过程生成'。这意味着,如果您在加密应用程序中使用这些随机值作为熵,则不希望使用伪随机生成器。

然而,对于您的使用,我相信它会没问题 - 只需检查潜在的(极不可能的)冲突。

您要做的就是创建一个随机字符串 - 不确保它是100%安全且完全随机。

答案 4 :(得分:-2)

尝试以下代码段: -

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

根据您的要求,文件名可能具有唯一性的字母数字名称。基于当前时间时间戳概念的唯一名称,因为当前时间将来不会重复,为了使其强大,我已应用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;

由于