Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-哈希算法-最快的实现_Java_Hash_Md5_Sha2 - Fatal编程技术网

Java-哈希算法-最快的实现

Java-哈希算法-最快的实现,java,hash,md5,sha2,Java,Hash,Md5,Sha2,我想知道Java哈希算法的最佳和最快实现是什么,特别是MD5和SHA-2 512(SHA512)或256。我想要一个函数获取一个字符串作为参数,并返回哈希作为结果。谢谢 编辑:用于将每个URL映射到唯一的哈希。由于MD5在这方面不太可靠,我更感兴趣的是为SHA-2算法找到最好、最快的实现。请注意,我知道即使是SHA-2也可能为某些URL生成相同的哈希值,但我可以接受。请查看以下内容: 此外: String hash=MD5.asHex(MD5.getHash(新文件名)) 编辑:我最初把这个问

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

编辑:用于将每个URL映射到唯一的哈希。由于MD5在这方面不太可靠,我更感兴趣的是为SHA-2算法找到最好、最快的实现。请注意,我知道即使是SHA-2也可能为某些URL生成相同的哈希值,但我可以接受。

请查看以下内容:

此外:


String hash=MD5.asHex(MD5.getHash(新文件名))

编辑:我最初把这个问题理解为“最快的哈希算法”是什么,它被澄清为“每个算法的最快实现”。这是一个有效的问题,其他人指出了更快的实现。然而,除非您在短时间内散列大量数据,否则这将不会有多大影响。我怀疑使用标准JCE提供的东西以外的东西是否值得花费时间和复杂性

对于URL地址,您需要在现代硬件上以每秒一百万以上的速度使用SHA-256进行哈希运算,以要求更快的速度。我无法想象大多数应用程序需要每秒超过1000次(每天超过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();
如果您是出于安全目的使用它,比如散列密码,那么您也应该在摘要中添加盐。如果要从哈希中提取可打印字符串,可以将其编码回十六进制字符串:

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();

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

第一件事:速度被高估了。您应该在声明给定的算法“太慢”之前采取措施。大多数情况下,哈希函数的速度并没有明显的差别。如果您对安全性有疑虑,那么首先选择一个足够安全的哈希函数,然后只考虑性能

此外,您希望散列“字符串”。Java
字符串
在内部是来自表示Unicode码点的
字符
值数组的块(实际上是Unicode 16位代码单元,使用UTF-16对码点进行编码)。哈希函数以位或字节序列作为输入。因此,您必须进行一个转换步骤,例如,
str.getBytes(“UTF-8”)
,以获得一组字节的字符串。与散列本身相比,转换步骤的成本可能不可忽略

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

您应该首先尝试将Java的
MessageDigest
API与标准(已安装)JCE提供程序一起使用(即调用
MessageDigest.getInstance(“SHA-256”)
),并测试结果。从理论上讲,JCE可以将调用映射到具有“本机”代码(用C或汇编编写)的实现,这将比使用Java更快

话虽如此

是C和Java中许多加密哈希函数的开源实现。代码已经针对速度进行了优化,实际上,Java版本比Sun/Oracle提供的标准JRE更快。在上一个链接失败的情况下使用(主主机服务器有时会因维护而停机,就像现在的情况一样)(警告:10 MB下载)。该档案还包含一份报告(该报告在2010年的会议上发表),其中给出了几个平台上的一些测量性能数据,用于SHA-2和即将到来的SHA-3的14个“第二轮”候选平台


但你真的应该在情况基准。例如,对一级缓存的影响可能会对性能产生重大影响,并且无法通过获取函数代码并单独运行它来准确预测。

对于字符串,只需调用
hashCode()
,因为这样会降低内存开销

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

public 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 < val.length; i += 8) {
        h = 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31 * h + 31 * 31 * 31 * 31
                * 31 * 31 * 31 * val[i] + 31 * 31 * 31 * 31 * 31 * 31
                * val[i + 1] + 31 * 31 * 31 * 31 * 31 * val[i + 2] + 31
                * 31 * 31 * 31 * val[i + 3] + 31 * 31 * 31 * val[i + 4]
                + 31 * 31 * val[i + 5] + 31 * val[i + 6] + val[i + 7];
    }
    for (; i + 3 < val.length; i += 4) {
        h = 31 * 31 * 31 * 31 * h + 31 * 31 * 31 * val[i] + 31 * 31
                * val[i + 1] + 31 * val[i + 2] + val[i + 3];
    }
    for (; i < val.length; i++) {
        h = 31 * h + val[i];
    }
    return h;
}
publicstaticinthash8(stringval)抛出UnsupportedEncodingException{
返回hash8(val.getBytes(“UTF-8”);
}
公共静态int hash8(字节[]val){
int h=1,i=0;
对于(;i+7