使用散列减少PHP中的时间戳长度

使用散列减少PHP中的时间戳长度,php,algorithm,hash,Php,Algorithm,Hash,我已经编写了自己的实现,生成了36个字符的长度标识符,您可以说我自己的UUID,它应该如下所示: 当前时间戳值加上-直到长度11 随机4个字符大写、小写和数字字符,后跟- 随机20个字符大写、小写和数字字符 此外,处理该ID的数据库表字段将位于bin排序规则中,以使其值区分大小写 结果ID可能类似于以下示例: 1491681481-TI5b-7aCPMLK9a7MMLoSdhr5d 在这里,时间戳长度是10,我想减少该长度,并用-替换差异。我尝试搜索PHP中可用的哈希算法: foreach(h

我已经编写了自己的实现,生成了36个字符的长度标识符,您可以说我自己的UUID,它应该如下所示:

  • 当前时间戳值加上-直到长度11
  • 随机4个字符大写、小写和数字字符,后跟-
  • 随机20个字符大写、小写和数字字符
  • 此外,处理该ID的数据库表字段将位于bin排序规则中,以使其值区分大小写

    结果ID可能类似于以下示例:

    1491681481-TI5b-7aCPMLK9a7MMLoSdhr5d
    
    在这里,时间戳长度是
    10
    ,我想减少该长度,并用
    -
    替换差异。我尝试搜索PHP中可用的哈希算法:

    foreach(hash_algos() as $alg){
            $h = hash($alg,1491681054);
            echo $alg."==>".$h."== Length ". strlen($h)."\n<br>";
        }
    
    foreach(hash_algos()作为$alg){
    $h=散列($alg,1491681054);
    echo$alg.“==>”$h.“==Length.strlen($h)。“\n
    ”; }
    我发现有一些算法返回
    8
    字符长度,例如

  • 阿德勒32
  • crc32
  • crc32b
  • fnv132
  • fnv1a32
  • 那些散列算法对我来说很好。然而,我害怕碰撞

    我需要知道这些算法的冲突概率其中源字符串只是一个十进制数?换句话说,输入类型或格式是否应该降低这些算法中任何一种算法的冲突概率?

    根据评论,我做了一个简单的实现,将时间戳的十进制值转换为基于62的数字,即英语字母的数字、大小写之和,如下所示:

    <?php
    
    $stem = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    
    $old = 10; //original base -decimal-
    $new = strlen($stem); //new base
    $num = 1491681054; // decimal input
    $out = '';
    while($num > 0){
       $devide =  $num/$new ;    
       $result =  explode('.',$devide)[0]// could use floor();    
       $remind = $devide - $result;    
       $num = $result;
       $out = substr($stem,round($remind * $new),1).$out;
    }
    
    echo "<hr>";
    echo $out;
    // returns 1CWWnQ
    

    因为时间戳将是一个已知的因素,所以测试代码中的冲突不会花费太多时间work@nogad什么意思?但是,我不是说生成的整个
    ID
    ,在本主题中,我只是指哈希时间戳值。@SaidbakR我们在这里讨论的是什么样的流量?除非在几乎相同的时间内有成百上千个请求,否则您必须将其细分到最接近的毫秒。如果这也是与数据库相关的,那么您可以使用另一种方法。如果你想减少时间戳的长度,你可以把它转换成十六进制,这样你就不会失去任何唯一性。或者你甚至可以更进一步,把它转换成一个以X为基数的数字,其中X是有效字符的数目,例如a-z,a-z和0-9会给出62,显然,X越大,数字的长度就越小。例如,以70为基数,您可以轻松地用6个字符表示所有数字,最多11位。