Tho*_*nin 50
第一件事:速度被高估了.在声明给定算法"太慢"之前,您应该采取措施.大多数情况下,哈希函数速度无论如何都没有明显的差异.如果您对安全性有疑虑,那么首先选择一个足够安全的哈希函数,然后只关心性能.
而且,你想要散列"字符串".Java String内部是char表示Unicode代码点的值数组(实际上是使用UTF-16编码代码点的Unicode 16位代码单元).散列函数将位或字节序列作为输入.因此,您必须进行转换步骤,例如str.getBytes("UTF-8"),将字符串作为一堆字节获取.与散列本身相比,转换步骤可能具有不可忽略的成本.
注意:注意URL编码!在URL中,一些字节可以用以' %'符号开头的序列替换; 这是为了支持不可打印的字符,但它也可以用在"标准"字符上(例如,将' a' 替换为' %61').这意味着两个不同的字符串(在String.equals()某种意义上)实际上可能代表相同的URL(就URL处理而言).根据您的情况,这可能是也可能不是问题.
您应该首先尝试将Java的MessageDigestAPI与标准(已安装的)JCE提供程序(即您调用MessageDigest.getInstance("SHA-256"))一起使用,并对结果进行评分.从理论上讲,JCE可以将调用映射到具有"本机"代码(用C或汇编语言编写)的实现,这将比使用Java获得的更快.
话虽如此...
sphlib是许多加密哈希函数的开源实现,在C和Java中.代码已针对速度进行了优化,实际上,Java版本比Sun/Oracle提供的标准JRE更快.如果上一个链接失败,请使用此链接(主要主机服务器有时会停机进行维护,现在似乎就是这种情况)(警告:10 MB下载).该档案还包含一份报告(在2010年第二届SHA-3候选人会议上发布),该报告在几个平台上提供了一些测量的性能数据,SHA-2和即将到来的SHA-3的14个"第二轮"候选人.
但你真的应该制定情况基准.例如,对L1缓存的影响会对性能产生严重影响,并且无法通过获取功能代码并单独运行来准确预测.
Whi*_*g34 21
编辑:我最初读的问题是什么是"最快的哈希算法",它已被澄清为"每个算法的最快实现".这是一个有效的问题,其他人已指出更快的实施.但是,除非你在很短的时间内散列大量数据,否则它根本不重要.我怀疑使用标准JCE提供的东西以外的其他东西通常是值得花时间和复杂性的.
对于URL地址,您需要在现代硬件上以每秒一百万的 SHA-256进行散列,以便更快地获得更快的内容.我无法想象大多数应用程序每秒需要超过一千(每天超过8600万),这意味着用于散列的总CPU时间远远小于1%.因此,即使您拥有无限快速的哈希算法,您也只能将整体性能提升1%.
原始答案:获得最好和最快的两者是相互矛盾的.更好的哈希值通常较慢.如果你真的需要速度和安全性并不是一个问题,那么使用MD5.如果您需要最好的安全性,那么请使用SHA-256甚至SHA-512.你没有提到你正在使用它的是什么,所以很难推荐其中一个.你可能最安全的使用SHA-256,因为无论如何它应该足够快速用于现代硬件上的大多数用例.这是你如何做到的:
String input = "your string";
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(input.getBytes("UTF-8"));
byte[] hash = digest.digest();
Run Code Online (Sandbox Code Playgroud)
如果您出于安全目的使用它,例如散列密码,那么您也应该在摘要中添加salt.如果你想要一个可打印的字符串,你可以将它编码回十六进制的字符串:
static char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
StringBuilder sb = new StringBuilder(hash.length * 2);
for (byte b : hash) {
sb.append(HEX_CHARS[(b & 0xF0) >> 4]);
sb.append(HEX_CHARS[b & 0x0F]);
}
String hex = sb.toString();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
66757 次 |
| 最近记录: |