关于Java:Java 您所在的位置:网站首页 测智商60题 关于Java:Java

关于Java:Java

#关于Java:Java| 来源: 网络整理| 查看: 265

我想知道什么是Java哈希算法的最佳和最快实现,尤其是MD5和SHA-2 512(SHA512)或256。我想要一个函数来获取字符串作为参数并返回哈希值。 谢谢你

编辑:这是用于将每个URL映射到唯一的哈希。 由于MD5在该领域的可靠性不高,因此我对寻找SHA-2算法的最佳和最快实现更感兴趣。 请注意,我知道即使SHA-2可能也会为某些URL产生相同的哈希,但是我可以接受。

相关讨论 我建议不要使用MD5 ...它非常坏。 Java附带的实现是否不足以达到您的目的?我可以使用笔记本电脑上的SHA-256通过MessageDigest每秒提供超过100MB的速度。甚至是随机的MD5哈希冲突的几率都是这样,如果您有数十亿个文档,则流星撞击您读到的确切秒数的可能性更大。对于唯一标识,MD5就足够了。仅当它用于安全目的并且有人明确地试图引起您应关注的冲突时(对于URL而言,这非常困难)。 您知道,我想在那里找到BEST的实现。如果有比MessageDigest更好的一个,为什么不使用它呢? 看一下Guava Hashing,它有一些可能有用的哈希实用程序。 仅供参考。MessageDigest算法的快速比较(左侧更快):MD5> SHA-1> SHA-256> MD2。 (MD5大约是SHA-256的两倍。...MD2慢10倍) @PimpTrizkit谢谢

首先,速度过高。在声明给定算法"太慢"之前,应先采取措施。在大多数情况下,哈希函数的速度不会产生明显的差异。如果您对安全性存有疑虑,则首先选择一个足够安全的哈希函数,然后才担心性能。

此外,您想散列"字符串"。 Java String在内部是char值数组中的一个块,这些值表示Unicode代码点(实际上是使用UTF-16编码代码点的Unicode 16位代码单元)。哈希函数将一系列位或字节作为输入。因此,您将需要执行一个转换步骤,例如str.getBytes("UTF-8"),以获得一串字节的字符串。与散列本身相比,转换步骤的成本很可能不可忽略。

注意:谨防URL编码!在URL中,可以将某些字节替换为以'%'符号开头的序列。这旨在支持不可打印的字符,但也可以用于"标准"字符(例如,将" a"替换为" %61")。这意味着两个不同的字符串(在String.equals()意义上)实际上可以表示相同的URL(就URL处理而言)。根据您的情况,这可能会或可能不会成为问题。

您应该首先尝试将Java的MessageDigest API与标准的(已安装)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缓存的影响可能会对性能产生巨大影响,并且无法通过获取功能代码并单独运行来准确预测。

相关讨论 谢谢。这似乎是我一直在寻找的东西。非常复杂的答案。 (尽管我已经打算按照您的建议去做,但是无论如何对将来的读者都是有益的)。关于URL字符的要点,我会在项目中尝试意识到这一点。

编辑:我最初将问题理解为什么是"最快的哈希算法",并且已被澄清为"每种算法的最快实现"。这是一个有效的问题,其他人指出了更快的实现方式。但是,除非您在短时间内对大量数据进行哈希处理,否则根本就不会有太大关系。我怀疑使用标准JCE所提供的东西以外的其他东西通常值得花费时间和复杂性。

对于URL地址,您需要在现代硬件上以每秒百万分之一以上的SHA-256进行散列,以要求更快的速度。我无法想象大多数应用程序每秒需要超过一千个(每天超过8600万个),这意味着散列所花的总CPU时间将远远少于1%。因此,即使您拥有无限快速的哈希算法,您最多也只能将整体性能提高1%。

原始答案:取得最佳和最快的结果是相互矛盾的。较好的哈希值通常较慢。如果您确实需要速度,而安全性不是您的首要考虑,那么请使用MD5。如果您需要最佳的安全性,则选择SHA-256甚至SHA-512。您没有提到您使用它的目的,因此很难推荐其中一个。 SHA-256可能是最安全的选择,因为对于现代硬件上的大多数用例而言,它应该足够快。您可以按照以下方法进行操作:

1234String input ="your string"; MessageDigest digest = MessageDigest.getInstance("SHA-256"); digest.update(input.getBytes("UTF-8")); byte[] hash = digest.digest();

如果出于安全性目的将此密码(例如对密码进行哈希处理),则还应在摘要中添加盐。如果您希望散列中不包含可打印的字符串,则可以将其编码回十六进制的字符串:

12345678static 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(); 相关讨论 我将问题理解为"每种算法的最快实现",而不是最快的算法。 但是对这个不错的" toHexString"实现+1。 @Pa?lo:啊,你可能是对的。 OP可能应该阐明并为我们提供有关用例的一些见解。 是的,这正是我的意思:每种算法的最快实现。我认为最快的MD5可能是"最快的MD5",但我尚未对其进行测试。我编辑了问题以进一步阐明。顺便说一句,我喜欢您代码的字符串转换部分。 +1 由于速度似乎很重要,因此可以通过用char[]替换十六进制数字String并使用HEX_DIGITS[(b & 0xF0) >> 4]而不是调用charAt()来稍微改善toHexString()的实现。在(可能有缺陷的)微基准测试中,这证明快了约30%。 谢谢。在您提出建议之前,我在类中使用了私有常量String,它提高了性能,但我将其更改为char数组。 更新了答案,建议使用char[]进行十六进制转换以获得更好的性能。

要考虑的另一件事是使用MD4。它不如MD5安全,但计算速度更快。 Windows XP和Windows XP以前曾在MD4中存储和交换密码,因此我们使用此哈希,因为它仍然允许我们向该平台提供身份验证服务。

相关讨论 MD4和MD5均损坏。我不建议使用任何一个。 我也是,我不打算在我的项目中使用它作为主要方案。如果用户选择他/她想要它,我只是希望它可用。 MD4已完全损坏,您不妨使用CRC

查看这些:许多S??HA / MD5示例

也: 从同一线程:Fast MD5

字符串哈希= MD5.asHex(MD5.getHash(new File(filename)));

相关讨论 我以前都看过。快速MD5可能有用,但我期待更多。而且如上所述,我正在寻找更多快速的SHA-2实现。

考虑一下BLAKE2,它比上面提到的哈希更快,更安全。

MD5,SHA-1,SHA256和SHA-512易于扩展。

MD5和SHA-1容易发生冲突。

MD5容易受到前缀前缀冲突的影响。

SHA-3和BLAKE2没有已知的安全问题,并且可以生成不同长度的摘要。

当以硬件实现时,SHA-3最快。使用软件实现时,BLAKE2最快。

BLAKE2b针对64位平台进行了优化,可生成1到64字节之间任意大小的摘要。

BLAKE2s已针对8到32位平台进行了优化,并生成1到32字节之间任意大小的摘要。

这是AES,MD5,SHA-256和BLAKE2b的基准。

https://blake2.net/

https://www.cryptopp.com/benchmarks.html

在第一个链接中,BLAKE2b(947 Mbits)比SHA-256(413 Mbits)和MD5(632 Mbits)快得多。

在第二个链接中,AES-256 CBC(805 Mbits)和BLAKE2b(776 Mbits)的速度大约相等,并且比SHA-256(275 Mbits)和MD5(602)Mbits更快。

对于字符串,只需调用hashCode(),因为在内存开销方面更便宜。

否则,我建议将此代码用于私有哈希:

12345678910111213141516171819202122public static int hash8(String val) throws UnsupportedEncodingException {     return hash8(val.getBytes("UTF-8")); } public static int hash8(byte[] val) {     int h = 1, i = 0;     for (; i + 7


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有