PHP生成唯一ID 公认较为安全的写法 上传随机文件名

PHP生成随机文件名有多种方式,本次介绍一个在公认比较新、比较安全的随机ID函数。较老的方式一般单一使用rand函数生成随机数字,或者用md5,或者进一步使用uniqid()函数,但不论以上哪种方式,都存在可能重复的问题。我查阅了国外技术论坛,总结了一个名为unique_ID的函数,采用了目前公认较为安全、不容易出现重复的写法,优先使用random_bytes函数、openssl_random_pseudo_byte函数进行随机字符生成。

此函数可以用在各类需要生成唯一ID的场景中,一个非常普遍的场景就是上传图片名。

/**
* unique_ID
* 生成16位以上唯一ID
*
* @author Aspirant Zhang <admin@aspirantzhang.com>
* @param int $length 不含前缀的长度,最小16,建议20+
* @param str $prefix 前缀
* @return str $id
*/
function unique_ID($length = 16,$prefix = ''){
    $id = $prefix;
    $addLength = $length - 13;
    $id .= uniqid();
    if (function_exists('random_bytes')) {
        $id .= substr(bin2hex(random_bytes(ceil(($addLength) / 2))),0,$addLength);
    } elseif (function_exists('openssl_random_pseudo_bytes')) {
        $id .= substr(bin2hex(openssl_random_pseudo_bytes(ceil($addLength / 2))),0,$addLength);
    } else {
        $id .= mt_rand(1*pow(10,($addLength)),9*pow(10,($addLength)));
    }
    return $id;
}

 

点赞
  1. 逍遥游说道:

    该方法循环执行500次,你试试?连测试都不测一下,放出来丢人现眼么?根本就做不到唯一不重复。

    1. aspirantzhang说道:

      您好,在收到您的留言后,我本人对此段程序进行了多次测试。基于PHP7.2,循环执行1万次,多次测试未发现重复值。
      程序核心是常见的唯一生成函数uniqid(),他生成的是13位,但如果单纯靠uniqid是会存在重复问题的。所以后面通过random_bytes、openssl_random_pseudo_byte进行了拓展。使原本的13位uniqid再拓展至少3位,最终构成至少16位的随机字符。总体逻辑应该正确,满足我所说的“较为安全,不容易出现重复”。
      这段程序我已在生产环境中应用多年,未发现问题。不太清楚您那边是出了怎样的问题,如果本程序真的是有很大问题的话,我希望您给出一些建设性的建议。
      不过,虽然未发现有重大问题,但我发现我的函数注释“最小14,建议16+”可能存在问题,14不太安全,我已修改为“最小16,建议20+”。
      感谢您的留言和提醒,但我认为,敢写出来,写错了敢认错,就不丢人。

      1. 黄焯华说道:

        完全不丢人,坚持做自己,世界上学习编程最快的方式就是不断练习和自己做笔记,只有这样才能思考明白。

发表评论

电子邮件地址不会被公开。 必填项已用*标注