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

问题描述 投票:0回答:8

我需要用简短的唯一标识符来命名上传的文件,例如

nYrnfYEv
a4vhAoFG
hwX6aOr7
。如何确保文件的唯一性?

node.js file-upload uniqueidentifier
8个回答
25
投票

更新: shortid 已弃用。请使用Nano ID。下面的答案也适用于 Nano ID。


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

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

A-Za-z0-9\_\-
)。

回答您(和其他发帖者)的疑虑:

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

19
投票

一种选择是生成唯一标识符 (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。阅读模块的文档以熟悉这些内容。


5
投票

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

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

2
投票
export default generateRandom = () => Math.random().toString(36).substring(2, 15) + Math.random().toString(23).substring(2, 5);

就这么简单!


0
投票
function uniqueFileName( filePath, stub)
{
    let id = 0;
    let test = path.join(filePath, stub + id++);
    while (fs.existsSync(test))
    {
        test = path.join(filePath, stub + id++);
    }
    return test;
}

0
投票
function GetTempName()
{
    function gen(count) 
    { 
        let str = '';
        for (let i = 1; i <= count; i++) 
        {
            str += Math.floor(Math.random()*35).toString(36);
        }
        return  str;
    }
    return gen(8)+'-'+gen(4)+'-'+gen(4)+'-'+gen(4)+'-'+gen(12);
    //return gen(5);
    
}

for (let index = 0; index < 200; index++) {
    console.log(GetTempName());
}

-5
投票

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

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

但是,对于您的使用,我相信它会很好 - 只需检查潜在的(极不可能的)冲突。

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


-6
投票

尝试以下片段:-

    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;

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.