如何为android中的字符串输入生成唯一的哈希码...?

Posted

技术标签:

【中文标题】如何为android中的字符串输入生成唯一的哈希码...?【英文标题】:How to generate a unique hash code for string input in android...? 【发布时间】:2011-09-01 12:22:39 【问题描述】:

我想为 android 中的字符串生成一个唯一的哈希码。 是否有任何预定义的库,或者我们必须手动生成。请任何知道的人提供链接或代码。

【问题讨论】:

字符串的内置 hashCode 怎么样? 唯一哈希码?为什么?你怎么会认为这是可能的? 请详细说明。唯一的哈希码是不可能的(除非它们可以有无限长),因为可能的字符串是无限的。 那是完全错误的。我能想到五种方法来创建一个独特的哈希码。这一切都从重写 hashCode () 函数开始。无论如何,最后一条评论有点过于简单化了:如果在足够大的域上使用强大的生成器创建散列,那么发生冲突的机会可能会非常小。如果您覆盖 hashCode 以使用线程安全增量器,则您可以拥有唯一值。但是,大多数时候,如果正确实施,它只是无关紧要概率。 您不知道 OP 的上下文是什么。完全不知道。假设当他说“独特”时,他并不意味着这是一个巨大的延伸。无论如何,挑战仍然存在:告诉我们如何做。 【参考方案1】:

这取决于你的意思:

如前所述,String.hashCode() 为您提供 32 位哈希码。

如果您想要(比如说)一个 64 位哈希码,您可以自己轻松实现它。

如果您想要字符串的加密哈希,Java 加密库包括 MD5、SHA-1 等的实现。您通常需要将字符串转换为字节数组,然后将其提供给哈希生成器/摘要生成器。例如,请参阅@Bryan Kemp 的回答。

如果您想要一个保证唯一哈希码,那么您就不走运了。哈希和哈希码是非唯一的。

长度为 N 的 Java 字符串具有65536 ^ N 可能的状态,并且需要一个带有16 * N 位的整数来表示所有可能的值。如果你写了一个哈希函数,它产生的整数范围更小(例如,小于16 * N 位),你最终会发现多个字符串哈希到同一个整数的情况;即哈希码不能是唯一的。这称为Pigeonhole Principle,并且有一个直接的数学证明。 (你不能打数学赢!)

但是,如果“可能是唯一的”具有非常小的非唯一性机会是可以接受的,那么加密哈希是一个很好的答案。数学将告诉您哈希必须有多大(即多少位)才能实现给定(足够低)的非唯一性概率。

【讨论】:

64 位哈希码:如果您想要一个 64 位哈希码,为了完整性,来自***.com/questions/1660501/… 中的 sfussenegger 那么,一个32位的hash只能唯一标识2个字符的String吗? 基本上......是的。 (假设字符 == 任意 char 值。如果字符表示 Unicode 代码点...或(比如)ASCII 代码点,情况会变得更复杂。)【参考方案2】:

这是我用来创建消息摘要哈希的类

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Sha1Hex 

    public String makeSHA1Hash(String input)
            throws NoSuchAlgorithmException, UnsupportedEncodingException
        
            MessageDigest md = MessageDigest.getInstance("SHA1");
            md.reset();
            byte[] buffer = input.getBytes("UTF-8");
            md.update(buffer);
            byte[] digest = md.digest();

            String hexStr = "";
            for (int i = 0; i < digest.length; i++) 
                hexStr +=  Integer.toString( ( digest[i] & 0xff ) + 0x100, 16).substring( 1 );
            
            return hexStr;
        

【讨论】:

【参考方案3】:
String input = "some input string";
int hashCode = input.hashCode();
System.out.println("input hash code = " + hashCode);

【讨论】:

@Vladimir - 根据定义,没有哈希码被定义为唯一的! Hashcode需要很好的分布,唯一性的想法是对OP的错误理解。 如果哈希码是唯一的,那将是一种非常糟糕的压缩算法。 例如尝试 "Z@S.ME" 和 "Z@RN.E" 它们在使用 hashCode 时具有相同的哈希值;) @Simon,刚刚在 .NET 中运行了您的示例,因为我很好奇。它们必须具有不同的基本哈希算法,因为它们在那里不完全匹配。 dotnetfiddle.net/6YJRpV 也许 OP 所说的 unique 的意思是:unique-for-a-given-input-string(不应该为同一个字符串生成两个哈希)。【参考方案4】:

我使用它作为我的 EhCacheManager 内存映射中的密钥进行测试 ....

我想它更干净

   /**
     * Return Hash256 of String value
     *
     * @param text
     * @return 
     */
    public static String getHash256(String text) 
        try 
            return org.apache.commons.codec.digest.DigestUtils.sha256Hex(text);
         catch (Exception ex) 
            Logger.getLogger(HashUtil.class.getName()).log(Level.SEVERE, null, ex);
            return "";
        
    

我正在使用 maven,但这是 jar commons-codec-1.9.jar

【讨论】:

【参考方案5】:

您可以使用此代码为给定字符串生成 has 代码。

int hash = 7;
for (int i = 0; i < strlen; i++) 
    hash = hash*31 + charAt(i);

【讨论】:

你为什么从 7 点开始?【参考方案6】:

对我来说很有效

   public static long getUniqueLongFromString (String value)
       return  UUID.nameUUIDFromBytes(value.getBytes()).getMostSignificantBits();
    

【讨论】:

【参考方案7】:

几行java代码。

public static void main(String args[]) throws Exception
       String str="test string";
       MessageDigest messageDigest=MessageDigest.getInstance("MD5");
       messageDigest.update(str.getBytes(),0,str.length());
       System.out.println("MD5: "+new BigInteger(1,messageDigest.digest()).toString(16));

【讨论】:

【参考方案8】:

我们来看看股票的hashCode()方法:

public int hashCode() 
    int h = hash;
    if (h == 0 && count > 0) 
        for (int i = 0; i < count; i++) 
            h = 31 * h + charAt(i);
        
        hash = h;
    
    return h;

上面的代码块来自 java.lang.String 类。如您所见,它是一个 32 位哈希码,如果您在小规模数据上使用它就足够公平了。如果您正在寻找超过 32 位的哈希码,您可能需要查看此链接: http://www.javamex.com/tutorials/collections/strong_hash_code_implementation.shtml

【讨论】:

以上是关于如何为android中的字符串输入生成唯一的哈希码...?的主要内容,如果未能解决你的问题,请参考以下文章

如何为数据库中的一列生成唯一的字符串?

为所有字谜生成相同的唯一哈希码

如何为 BigQuery 表中的记录生成唯一键值?

如何为 Spark RDD 中的元素分配唯一的连续编号

Firebase:如何为键生成唯一的数字 ID?

如何为rdd的每一行生成一个哈希? (PYSPARK)