非encryption用途最快的哈希值?
我基本上是准备把短语放在数据库中,他们可能是畸形的,所以我想存储它们的简短散列(我将只是比较它们是否存在,所以散列是理想的)。
我假设MD5在十万次以上的请求中相当慢,所以我想知道什么是最好的方法来散列短语,也许推出我自己的散列函数或使用hash('md4', '...'
将更快结束?
我知道MySQL有MD5(),所以这将补充一点速度的查询结束,但也许还有一个更快的哈希函数在MySQL中,我不知道这将与PHP的工作..
CRC32是相当快,有一个function: http : //www.php.net/manual/en/function.crc32.php
但是您应该意识到CRC32与MD5或甚至SHA-1哈希将具有更多的冲突,这仅仅是因为缩短了长度(32比特相比于128比特和160比特)。 但是,如果你只是想检查一个存储的string是否损坏,你会没事的CRC32。
fcn time generated hash crc32: 0.03163 798740135 md5: 0.0731 0dbab6d0c841278d33be207f14eeab8b sha1: 0.07331 417a9e5c9ac7c52e32727cfd25da99eca9339a80 xor: 0.65218 119 xor2: 0.29301 134217728 add: 0.57841 1105
用于生成这个代码的代码是:
$loops = 100000; $str = "ana are mere"; echo "<pre>"; $tss = microtime(true); for($i=0; $i<$loops; $i++){ $x = crc32($str); } $tse = microtime(true); echo "\ncrc32: \t" . round($tse-$tss, 5) . " \t" . $x; $tss = microtime(true); for($i=0; $i<$loops; $i++){ $x = md5($str); } $tse = microtime(true); echo "\nmd5: \t".round($tse-$tss, 5) . " \t" . $x; $tss = microtime(true); for($i=0; $i<$loops; $i++){ $x = sha1($str); } $tse = microtime(true); echo "\nsha1: \t".round($tse-$tss, 5) . " \t" . $x; $tss = microtime(true); for($i=0; $i<$loops; $i++){ $l = strlen($str); $x = 0x77; for($j=0;$j<$l;$j++){ $x = $x xor ord($str[$j]); } } $tse = microtime(true); echo "\nxor: \t".round($tse-$tss, 5) . " \t" . $x; $tss = microtime(true); for($i=0; $i<$loops; $i++){ $l = strlen($str); $x = 0x08; for($j=0;$j<$l;$j++){ $x = ($x<<2) xor $str[$j]; } } $tse = microtime(true); echo "\nxor2: \t".round($tse-$tss, 5) . " \t" . $x; $tss = microtime(true); for($i=0; $i<$loops; $i++){ $l = strlen($str); $x = 0; for($j=0;$j<$l;$j++){ $x = $x + ord($str[$j]); } } $tse = microtime(true); echo "\nadd: \t".round($tse-$tss, 5) . " \t" . $x;
排名列表中,每个循环与所有其他人共享相同的东西到地下室。
<?php set_time_limit(720); $begin = startTime(); $scores = array(); foreach(hash_algos() as $algo) { $scores[$algo] = 0; } for($i=0;$i<10000;$i++) { $number = rand()*100000000000000; $string = randomString(500); foreach(hash_algos() as $algo) { $start = startTime(); hash($algo, $number); //Number hash($algo, $string); //String $end = endTime($start); $scores[$algo] += $end; } } asort($scores); $i=1; foreach($scores as $alg => $time) { print $i.' - '.$alg.' '.$time.'<br />'; $i++; } echo "Entire page took ".endTime($begin).' seconds<br />'; echo "<br /><br /><h2>Hashes Compared</h2>"; foreach($scores as $alg => $time) { print $i.' - '.$alg.' '.hash($alg,$string).'<br />'; $i++; } function startTime() { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; return $mtime; } function endTime($starttime) { $mtime = microtime(); $mtime = explode(" ",$mtime); $mtime = $mtime[1] + $mtime[0]; $endtime = $mtime; return $totaltime = ($endtime - $starttime); } function randomString($length) { $characters = '0123456789abcdefghijklmnopqrstuvwxyz'; $string = ''; for ($p = 0; $p < $length; $p++) { $string .= $characters[mt_rand(0, strlen($characters) - 1)]; } return $string; } ?>
和输出
1 - crc32b 0.111036300659 2 - crc32 0.112048864365 3 - md4 0.120795726776 4 - md5 0.138875722885 5 - sha1 0.146368741989 6 - adler32 0.15501332283 7 - tiger192,3 0.177447080612 8 - tiger160,3 0.179498195648 9 - tiger128,3 0.184012889862 10 - ripemd128 0.184052705765 11 - ripemd256 0.185411214828 12 - salsa20 0.198500156403 13 - salsa10 0.204956293106 14 - haval160,3 0.206098556519 15 - haval256,3 0.206891775131 16 - haval224,3 0.206954240799 17 - ripemd160 0.207638263702 18 - tiger192,4 0.208125829697 19 - tiger160,4 0.208438634872 20 - tiger128,4 0.209359407425 21 - haval128,3 0.210256814957 22 - sha256 0.212738037109 23 - ripemd320 0.215386390686 24 - haval192,3 0.215610980988 25 - sha224 0.218329429626 26 - haval192,4 0.256464719772 27 - haval160,4 0.256565093994 28 - haval128,4 0.257113456726 29 - haval224,4 0.258928537369 30 - haval256,4 0.259262084961 31 - haval192,5 0.288433790207 32 - haval160,5 0.290239810944 33 - haval256,5 0.291721343994 34 - haval224,5 0.294484138489 35 - haval128,5 0.300224781036 36 - sha384 0.352449893951 37 - sha512 0.354603528976 38 - gost 0.392376661301 39 - whirlpool 0.629067659378 40 - snefru256 0.829529047012 41 - snefru 0.833986997604 42 - md2 1.80192279816 Entire page took 22.755341053 seconds Hashes Compared 1 - crc32b 761331d7 2 - crc32 7e8c6d34 3 - md4 1bc8785de173e77ef28a24bd525beb68 4 - md5 9f9cfa3b5b339773b8d6dd77bbe931dd 5 - sha1 ca2bd798e47eab85655f0ce03fa46b2e6e20a31f 6 - adler32 f5f2aefc 7 - tiger192,3 d11b7615af06779259b29446948389c31d896dee25edfc50 8 - tiger160,3 d11b7615af06779259b29446948389c31d896dee 9 - tiger128,3 d11b7615af06779259b29446948389c3 10 - ripemd128 5f221a4574a072bc71518d150ae907c8 11 - ripemd256 bc89cd79f4e70b73fbb4faaf47a3caf263baa07e72dd435a0f62afe840f5c71c 12 - salsa20 91d9b963e172988a8fc2c5ff1a8d67073b2c5a09573cb03e901615dc1ea5162640f607e0d7134c981eedb761934cd8200fe90642a4608eacb82143e6e7b822c4 13 - salsa10 320b8cb8498d590ca2ec552008f1e55486116257a1e933d10d35c85a967f4a89c52158f755f775cd0b147ec64cde8934bae1e13bea81b8a4a55ac2c08efff4ce 14 - haval160,3 27ad6dd290161b883e614015b574b109233c7c0e 15 - haval256,3 03706dd2be7b1888bf9f3b151145b009859a720e3fe921a575e11be801c54c9a 16 - haval224,3 16706dd2c77b1888c29f3b151745b009879a720e4fe921a576e11be8 17 - ripemd160 f419c7c997a10aaf2d83a5fa03c58350d9f9d2e4 18 - tiger192,4 112f486d3a9000f822c050a204d284d52473f267b1247dbd 19 - tiger160,4 112f486d3a9000f822c050a204d284d52473f267 20 - tiger128,4 112f486d3a9000f822c050a204d284d5 21 - haval128,3 9d9155d430218e4dcdde1c62962ecca3 22 - sha256 6027f87b4dd4c732758aa52049257f9e9db7244f78c132d36d47f9033b5c3b09 23 - ripemd320 9ac00db553b51662826267daced37abfccca6433844f67d8f8cfd243cf78bbbf86839daf0961b61d 24 - haval192,3 7d706dd2d37c1888eaa53b154948b009e09c720effed21a5 25 - sha224 b6395266d8c7e40edde77969359e6a5d725f322e2ea4bd73d3d25768 26 - haval192,4 d87cd76e4c8006d401d7068dce5dec3d02dfa037d196ea14 27 - haval160,4 f2ddd76e156d0cd40eec0b8d09c8f23d0f47a437 28 - haval128,4 f066e6312b91e7ef69f26b2adbeba875 29 - haval224,4 1b7cd76ea97c06d439d6068d7d56ec3d73dba0373895ea14e465bc0e 30 - haval256,4 157cd76e8b7c06d432d6068d7556ec3d66dba0371c95ea14e165bc0ec31b9d37 31 - haval192,5 05f9ea219ae1b98ba33bac6b37ccfe2f248511046c80c2f0 32 - haval160,5 e054ec218637bc8b4bf1b26b2fb40230e0161904 33 - haval256,5 48f6ea210ee1b98be835ac6b7dc4fe2f39841104a37cc2f06ceb2bf58ab4fe78 34 - haval224,5 57f6ea2111e1b98bf735ac6b92c4fe2f43841104ab7cc2f076eb2bf5 35 - haval128,5 ccb8e0ac1fd12640ecd8976ab6402aa8 36 - sha384 bcf0eeaa1479bf6bef7ece0f5d7111c3aeee177aa7990926c633891464534cd8a6c69d905c36e882b3350ef40816ed02 37 - sha512 8def9a1e6e31423ef73c94251d7553f6fe3ed262c44e852bdb43e3e2a2b76254b4da5ef25aefb32aae260bb386cd133045adfa2024b067c2990b60d6f014e039 38 - gost ef6cb990b754b1d6a428f6bb5c113ee22cc9533558d203161441933d86e3b6f8 39 - whirlpool 54eb1d0667b6fdf97c01e005ac1febfacf8704da55c70f10f812b34cd9d45528b60d20f08765ced0ab3086d2bde312259aebf15d105318ae76995c4cf9a1e981 40 - snefru256 20849cbeda5ddec5043c09d36b2de4ba0ea9296b6c9efaa7c7257f30f351aea4 41 - snefru 20849cbeda5ddec5043c09d36b2de4ba0ea9296b6c9efaa7c7257f30f351aea4 42 - md2 d4864c8c95786480d1cf821f690753dc
在xxhash网站上有一个速度比较。 复制粘贴在这里:
Name Speed Q.Score Author xxHash 5.4 GB/s 10 MumurHash 3a 2.7 GB/s 10 Austin Appleby SpookyHash 2.0 GB/s 10 Bob Jenkins SBox 1.4 GB/s 9 Bret Mulvey Lookup3 1.2 GB/s 9 Bob Jenkins CityHash64 1.05 GB/s 10 Pike & Alakuijala FNV 0.55 GB/s 5 Fowler, Noll, Vo CRC32 0.43 GB/s 9 MD5-32 0.33 GB/s 10 Ronald L. Rivest SHA1-32 0.28 GB/s 10
所以看起来xxHash是迄今为止最快的一个,而许多其他的则击败了较旧的哈希,如CRC32,MD5和SHA。
https://code.google.com/p/xxhash/
请注意,这是32位编译的顺序。 在64位编译时,性能顺序可能非常不同。 一些散列基于64位乘法和提取。
+-------------------+---------+------+--------------+ | NAME | LOOPS | TIME | OP/S | +-------------------+---------+------+--------------+ | sha1ShortString | 1638400 | 2.85 | 574,877.19 | | md5ShortString | 2777680 | 4.11 | 675,834.55 | | crc32ShortString | 3847980 | 3.61 | 1,065,922.44 | | sha1MediumString | 602620 | 4.75 | 126,867.37 | | md5MediumString | 884860 | 4.69 | 188,669.51 | | crc32MediumString | 819200 | 4.85 | 168,907.22 | | sha1LongString | 181800 | 4.95 | 36,727.27 | | md5LongString | 281680 | 4.93 | 57,135.90 | | crc32LongString | 226220 | 4.95 | 45,701.01 | +-------------------+---------+------+--------------+
看起来crc32对于小消息(在本例中是26个字符)更快,而对于更长的消息(在这种情况下> 852个字符)则md5更快。
而不是假定MD5是“相当慢”,试试吧。 在简单的PC(我的2.4 GHz Core2,使用单个内核)上简单的基于C的MD5实现可以每秒散列6 百万条小信息。 这里有一个小消息,最多55字节。 对于更长的消息,MD5哈希速度与消息大小成线性关系,即以每秒大约400兆字节的速度处理数据。 您可能会注意到,这是一个好的硬盘或千兆位以太网卡的最大速度的四倍。
由于我的电脑有四个内核,这意味着散列数据的速度与我的硬盘一样快,可以提供或接收最多6%的可用计算能力。 散列速度成为一个瓶颈,甚至在个人电脑上引起一个明显的代价需要一个非常特殊的情况。
在较小的体系结构中,散列速度可能变得有些相关,您可能需要使用MD4。 对于非encryption目的,MD4是很好的(并且为了encryption的目的,你不应该使用MD5)。 据报道,在基于ARM的平台上,MD4甚至比CRC32更快。
2016年更新:事情已经演变。
目前的build议应该是使用Murmur哈希族 (具体见murmur2或murmur3变种)。
虚拟散列是为了快速散列而devise的,其冲突最小(比CRC,MDx和SHAx快得多)。 这是完美的寻找重复,非常适合HashTable索引。
事实上,它被许多现代数据库(Redis,ElastisSearch,Cassandra)用来计算各种散列用于各种目的。 这个特定的algorithm是当前十年中许多性能改进的根源。
它也用于Bloom Filters的实现。 你应该知道,如果你正在寻找“快速哈希”,你可能正面临一个典型的问题,由布卢姆filter解决。 😉
注意 :杂音是通用散列,意思是非密码。 它不会阻止find生成散列的源文本。 散列密码是不合适的。
更多细节: MurmurHash – 这是什么?
我build议urlencode()或base64_encode()出于以下原因:
- 你不需要密码学
- 你想要速度
- 您需要一种方法来识别唯一的string,同时清理“格式不正确”的string
在这些回复的其他地方调整基准代码,我已经certificate,这两种方法都比任何散列algorithm快。 根据您的应用程序,您可以使用urlencode()或base64_encode()清理要存储的任何“格式不正确”的string。
如果你正在寻找快速和独特的,我推荐xxHash或使用新的cpu的crc32c内置命令的东西,请参阅https://stackoverflow.com/a/11422479/32453 。 如果你不关心碰撞的可能性,它也可能连接到更快的哈希。
第一步: 安装libsodium
第二步:使用\Sodium\crypto_generichash()
说明:它使用BLAKE2b 。
Adler32在我的机器上performance最好。 和md5()
结果比crc32()
更快。
散列内md5的实现比md5()快一点。 所以这可以是一个选项或其他一些,请尝试:
echo '<pre>'; $run = array(); function test($algo) { #static $c = 0; #if($c>10) return; #$c++; $tss = microtime(true); for($i=0; $i<100000; $i++){ $x = hash($algo, "ana are mere"); } $tse = microtime(true); $GLOBALS['run'][(string)round($tse-$tss, 5)] = "\nhash({$algo}): \t".round($tse-$tss, 5) . " \t" . $x; #echo "\n$i nhash({$algo}): \t".round($tse-$tss, 5) . " \t" . $x; } array_map('test', hash_algos()); ksort($run); print_r($run); echo '</pre>';
CRC32速度更快,但比MD5和SHA1更安全。 MD5和SHA1之间没有太多的速度差异。