我需要用类似nYrnfYEv
、a4vhAoFG
、hwX6aOr7
这样的短唯一标识为上传的文件命名。 我该如何确保文件的唯一性?
我需要用类似nYrnfYEv
、a4vhAoFG
、hwX6aOr7
这样的短唯一标识为上传的文件命名。 我该如何确保文件的唯一性?
更新:shortid已弃用,请使用Nano ID代替。下面的答案同样适用于Nano ID。
A-Za-z0-9\_-
)。一个选择是生成唯一标识符(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。
注意:还有其他类型的UUID可供选择。请阅读该模块的文档以熟悉它们。
function getRandomFileName() {
var timestamp = new Date().toISOString().replace(/[-:.]/g,"");
var random = ("" + Math.random()).substring(2, 8);
var random_number = timestamp+random;
return random_number;
}
export default generateRandom = () => Math.random().toString(36).substring(2, 15) + Math.random().toString(23).substring(2, 5);
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;
}
我认为您可能对真随机和伪随机感到困惑。
伪随机字符串“通常表现出统计上的随机性,同时由完全确定性的随机过程生成”。这意味着,如果您将这些随机值用作加密应用程序中的熵,则不应使用伪随机生成器。
然而,就您的使用而言,我认为这样做没问题——只需检查可能存在的(极少发生的)冲突即可。
您所要做的只是创建一个随机字符串——而不是确保它是100%安全和完全随机的。
crypto
模块比Math.random()
更好的PRNG. - ItalyPaleAle 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;
谢谢
getRandomSalt
总是生成相同的字符串。 - Erikfor(i=0; i < 60; ++i) console.log(new Date().getTime());
时,我可以看到时间戳重复了几十次。我想,如果您在运行代码的机器上保证消耗超过一毫秒的其余部分,则该评论是正确的。无论如何,大多数时间戳字符串都没有改变,因此对唯一性的贡献非常小。我在节点上运行它,在前60次迭代中就发生了冲突。运行了600次,得到了堆栈溢出(尝试证明递归停止!)。 - Ron Burk