php hash算法类

ash算法,又称散列算法,杂凑算法

它可以将一个长度不固定的数据,通过算法,获取其特征值生成一个固定的,较短的数据,压缩其文件标识.

实现用一个较短的数据进行标识一个大数据标识.比如用32位字符串的md5,标识整个文件

我们可以自定义一个算法,将中文字符串,只获取拼音首字母的特征,转成hash:

"仙士可"=>'xsk'

"阿伟死了"=>'awsl'

如果使用中文表示,需要的字符串长度是字母缩写的2-4倍.

重复性

通过上面的例子,我们可能会发现一些问题,例如: "啊我死了" ,"阿王死了",都会对应 'awsl'

这时候,就发生了 哈希冲突,  不同的数据,可能会因为提取特征值,而产生相同的hash结果

逆推性

可以发现,我们可以通过 "sl","sb","nt"等字母,很容易隐隐约约的知道原来的中文意思

这就造成了如果我们中文的一句话如果都有这些意思,那生成的hash重复性将会非常大.

因此,一个优秀的hash算法,应该具备以下条件:

1:正向快速计算,能通过输入的数据,在有限的时间,利用有限的资源就能计算出hash值(比如说你要用数据 做1亿次加减乘除法计算,虽然很难重复了,但是每次都计算1亿次,非常不现实)

2:逆向困难,hash字符串不能直接被逆向推算出.

3:输入敏感,原始信息就算多了一个空格,也应该跟原来的字符串非常不一致

4:冲突避免,hash的数据应该尽可能避免冲突,均匀分布,否则将失去hash本身的特性

目前最经典的hash算法有md5,time33,sha

在实际使用中,md5是字符串hash,并且性能较差,php在hashtable中hash计算使用的是time33算法.

最后附带上使用php实现的各种流行hash算法

<?php


class Hash
{

    /**
     * 加法hash
     * additiveHash
     * @param string $key
     * @param int    $mask
     * @return int
     * @author tioncico
     * Time: 11:38 上午
     */
    public static function additiveHash(string $key, $mask = 0x8765fed1)
    {
        for ($hash = strlen($key), $i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash += $charIndex;
        }
        return ($hash % $mask);
    }

    /**
     * 旋转hash
     * rotatingHash
     * @param string $key
     * @param int    $mask
     * @return int
     * @author tioncico
     * Time: 11:38 上午
     */
    public static function rotatingHash(string $key, $mask = 0x8765fed1)
    {
        for ($hash = strlen($key), $i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = ($hash << 4) ^ ($hash >> 28) ^ $charIndex;
        }
//        return ($hash % $prime);
        return ($hash ^ ($hash >> 10) ^ ($hash >> 20)) & $mask;
    }

    /**
     * 一次一个hash
     * oneByOneHash
     * @param     $key
     * @param int $mask
     * @return int
     * @author tioncico
     * Time: 11:38 上午
     */
    public static function oneByOneHash(string $key, $mask = 0x8765fed1)
    {
        for ($hash = strlen($key), $i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash += $charIndex;
            $hash += $hash << 10;
            $hash ^= $hash >> 6;
        }
        $hash += ($hash << 3);
        $hash ^= ($hash >> 11);
        $hash += ($hash << 15);
        return $hash & $mask;
    }

    public static function time33(string $key)
    {
        // hash($i) = hash($i-1) * 33 + str[$i]
        $hash = 5381;
        for ($i = 0; $i < strlen($key); $i++) {
            // (hash << 5) + hash 相当于 hash * 33
            //$hash = sprintf("%u", $hash * 33) + ord($s{$i});
            //$hash = ($hash * 33 + ord($s{$i})) & 0x7FFFFFFF;
            $charIndex = ord($key[$i]);
            $hash = ($hash << 5) + $hash + $charIndex;
        }
        return $hash & 0x7FFFFFFF;
    }

    public static function fnvHash(string $key, $mask = 0x8765fed1, $mShift = 0)
    {
        $hash = 2166136261;
        $p = 16777619;
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = ($hash * $p) ^ $charIndex;
        }
        if ($mShift == 0) {
            return $hash;
        }
        return ($hash ^ ($hash >> $mShift)) & $mask;
    }

    public static function fnvHash1(string $key)
    {
        $p = 16777619;
        $hash = 2166136261;
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = ($hash * $p) ^ $charIndex;
        }
        $hash += $hash << 13;
        $hash ^= $hash >> 7;
        $hash += $hash << 3;
        $hash ^= $hash >> 17;
        $hash += $hash << 5;
        return $hash;
    }

    public static function intHash(int $key)
    {
        $key += ~($key << 15);
        $key ^= ~(self::uRight($key, 10));
        $key += ~($key << 3);
        $key ^= ~(self::uRight($key, 6));
        $key += ~($key << 11);
        $key ^= ~(self::uRight($key, 16));
        return $key;
    }

    protected static function uRight($a, $n)
    {
        $c = 2147483647 >> ($n - 1);
        return $c & ($a >> $n);
    }


    public static function rsHash(string $key)
    {
        $b = 3787551;
        $a = 636789;
        $hash = 0;
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = ($hash * $a) + $charIndex;
            $a = $a * $b;
        }
        return ($hash & 0x7FFFFFFF);
    }

    public static function jsHash(string $key)
    {
        $hash = 1315423911;
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = (($hash << 5) + $charIndex + ($hash >> 2));
        }
        return ($hash & 0x7FFFFFFF);
    }

    public static function pjwHash(string $key)
    {
        $bitsInUnsignedInt = 32;
        $threeQuarters = ($bitsInUnsignedInt * 3) / 4;
        $oneEighth = $bitsInUnsignedInt / 8;
        $highBits = 0xFFFFFFFF << ($bitsInUnsignedInt - $oneEighth);
        $hash = 0;
        $test = 0;
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = ($hash << $oneEighth) + $charIndex;
            if (($test = $hash & $highBits) != 0) {
                $hash = (($hash ^ ($test >> $threeQuarters)) & (~$highBits));
            }
        }
        return ($hash & 0x7FFFFFFF);
    }

    public static function elfHash(string $key)
    {
        $hash = 0;
        $x = 0;
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = ($hash << 4) + $charIndex;
            if (($x = (int)$hash & 0xF0000000 != 0)) {
                $hash ^= ($x >> 24);
                $hash &= ~$x;
            }
        }
        return ($hash & 0x7FFFFFFF);
    }

    public static function bkdrHash(string $key)
    {
        $hash = 0;
        $seed = 131; //31 131 1313 13131 131313
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = ($hash * $seed) + $charIndex;
        }
        return ($hash & 0x7FFFFFFF);
    }

    public static function sdbmHash(string $key)
    {
        $hash = 0;
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = $charIndex + ($hash << 6) + ($hash >> 15) - $hash;
        }
        return ($hash & 0x7FFFFFFF);
    }

    public static function dekHash(string $key)
    {
        $hash = strlen($key);
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = ($hash << 5) ^ ($hash >> 27) ^ $charIndex;
        }
        return ($hash & 0x7FFFFFFF);
    }

    public static function apHash(string $key)
    {
        $hash = 0;
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash ^= (($i & 1) == 0) ? (($hash << 7) ^ $charIndex ^ ($hash >> 3)) : (~(($hash << 11) ^ $charIndex ^ ($hash >> 5)));
        }
        return ($hash & 0x7FFFFFFF);
    }

    public static function javaHash(string $key)
    {
        $hash = 0;
        for ($i = 0; $i < strlen($key); $i++) {
            $charIndex = ord($key[$i]);
            $hash = 31 * $hash + $charIndex;
        }
        return ($hash & 0x7FFFFFFF);
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 亿级数据判断 bitmap-布隆过滤器

    假设我们使用redis缓存了商品信息,当我们请求进来时,首先经过的是redis,当redis不存在时,才会去查找mysql.然后将mysql的数据缓存到redi...

    仙士可
  • php文件下载限速,文件断点续传,多线程下载文件原理解析

    可以看出,php实现浏览器下载文件,主要是靠header头的支持以及echo 文件数据,那么,该如何限制速度呢?可以通过限制输出频率吗?例如每次读取1024之后...

    仙士可
  • mvc深刻理解,logic,service,model层的作用

    mcv 是模型(model)-视图(view)-控制器(controller)的缩写  是软件设计的一个规范

    仙士可
  • 纸上谈兵: 哈希表 (hash table)

    HASH 哈希表(hash table)是从一个集合A到另一个集合B的映射(mapping)。映射是一种对应关系,而且集合A的某个元素只能对应集合B中的一个元素...

    Vamei
  • djb2 hash算法

    Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就...

    李小白是一只喵
  • 面试题,如何在千万级的数据中判断一个值是否存在?

    当你看到这个标题的时候,你也许会想我可以使用hashmap之类的来存储值,然后get就是了。又或者把数据存在数据库里然后去判断就可以了。

    ImportSource
  • hash散列 introduction

    hash散列是在记录的存储位置与他的关键字之间建立的对应关系f, 使得每个key都对应一个存储位置, 查找时根据key的hash去查找.

    CoffeeLand
  • 如果世界上只有一种数据结构,那么我选择哈希!

    来源:blog.csdn.net/liweisnake/article/details/104779497

    芋道源码
  • 【专业技术】STL hash_map使用(一)

    今天在使用STL中的hash_map模板遇到使用PTCHAR作为Key时无法对字符串进行正确比较的问题。 hash_map类在头文件hash_map中,和所有其...

    程序员互动联盟
  • Hash冲突和一致性

    在数据量很大的时候,就会出现hash之后的数值,指向相同的位置,也就是所谓的hash冲突。这个取决于hash算法的好坏,以及数据量的大小,hash算法越差,数据...

    灰子学技术

扫码关注云+社区

领取腾讯云代金券