• DJB Hash Function,也称times33算法, php的实现与分析-算法


    此文转载自:https://blog.csdn.net/weixin_43932088/article/details/85983436

    DJBX33A又叫Times33哈希算法的实现与分析
    算法:对字符串的每个字符,迭代的乘以33,目的把字符串转换成整数

    公式:   hash(i) = hash(i-1)*33 + str[i] ;

    乘于33是为了减少碰撞重复,简单点理解就是1+2和2+1是一样的,那1*33+2和2*33+1就不一样了。
    为什么要用33,因为33是一个素数,能更好的散列,PHP内置的Hash函数用的素数是5381
     

    OK,那我们用php来试一下他的实现

    <?php
    /*
    * DJBX33A又叫Times33哈希算法的实现与分析
    * Author: lms <php7在qq.com> QQ:二一九二4238
    *  转发请注明来源网址http://www.thinkunion.net
    *  https://blog.csdn.net/weixin_43932088
    */
    function hash0($str){
        $hash=0;
        for($i=0;$i<strlen($str);$i++){
            $hash=$hash*33 +ord($str{$i});
        }
        return $hash;
    }
    /*上面这个函数中,字符串可以有各种语言字符,长度可以很长,并不利于计算,我们可以用md5转换成32位*/
    function hash1($str){
        $hash=0;
        $str=md5($str);
        for($i=0;$i<32;$i++){
            $hash=$hash*33 +ord($str{$i});
            var_dump($hash);
        }
        return $hash;
    }
    /*
    结果:
    int(54)
    int(1833)
    int(60543)
    int(1998021)
    int(65934790)
    float(2175848122)
    float(71802988124)
    float(2369498608189)
    float(78193454070337)
    float(2.5803839843212E+15)
    float(8.5152671482599E+16)
    float(2.8100381589258E+18)
    float(9.273125924455E+19)
    float(3.0601315550702E+21)
    float(1.0098434131732E+23)
    float(3.3324832634714E+24)
    float(1.0997194769456E+26)
    float(3.6290742739204E+27)
    float(1.1975945103937E+29)
    float(3.9520618842993E+30)
    float(1.3041804218188E+32)
    float(4.3037953920019E+33)
    float(1.4202524793606E+35)
    float(4.6868331818901E+36)
    float(1.5466549500237E+38)
    float(5.1039613350783E+39)
    float(1.6843072405758E+41)
    float(5.5582138939002E+42)
    float(1.8342105849871E+44)
    float(6.0528949304574E+45)
    float(1.9974553270509E+47)
    float(6.5916025792681E+48)
    
    从结果可以看出,php由于是弱类型的语言,不必声明自动转换类型。
    到计算的第六次时int已经不够位数直接变在float型。
     */
    
    function hash2($str){
        $hash=0;
        $str=md5($str);
        for($i=0;$i<32;$i++){
            $hash=($hash<<5)+$hash+ord($str{$i});
            var_dump($hash);
        }
        return $hash;
    }
    /*(hash << 5) + hash 相当于 hash * 33  ,位移的操作比乘法更高效*/
    /*
    结果:
    int(54)
    int(1833)
    int(60543)
    int(1998021)
    int(65934790)
    float(2175848122)
    float(3083511388)
    float(2971628093)
    float(3574446657)
    float(1992622742)
    float(1332041144)
    float(1007684894)
    float(-1106136809)
    float(-2142776279)
    float(-1992140422)
    float(-1316124435)
    float(-482433340)
    float(1259569015)
    float(2911071886)
    float(1576091778)
    float(471421223)
    float(-1622968768)
    float(-2018361740)
    float(-2181427925)
    float(-3267644691)
    float(-4753059648)
    float(-6527112925)
    float(-4941328969)
    float(-4150065975)
    float(-3808190947)
    float(-5411216861)
    float(-6771464525)
     */
    /*
    上面函数可以看到,跟float类型按位与得到了负数,与float类型按位与?这样的操作对么?
    php并没有长整形,而计算中int一下就溢出了。
    那么得到的以上所有函数得到的值是不是我们想要的。未完待续。
     */
       

    更多内容详见微信公众号:Python测试和开发

    Python测试和开发

  • 相关阅读:
    ES6新特性
    浏览器兼容问题
    跨域
    箭头函数与普通函数的区别
    单页面应用
    vue试题
    Git 常用命令
    【分享代码】一个笨办法获取容器的剩余内存
    【笔记】thanos receiver的router模式
    【分享】让prometheus支持PUSH模式,可以使用remote write协议推送数据
  • 原文地址:https://www.cnblogs.com/phyger/p/14357660.html
Copyright © 2020-2023  润新知