我试图想出一个串好的哈希函数。 我想这可能是总结Unicode值的字符串中的前五个字符是一个好主意(假设它有五个,否则停止在那里结束)。 那会是一个好主意,还是坏事呢?
我在Java中这样做,但我无法想象这将使多大的差别。
我试图想出一个串好的哈希函数。 我想这可能是总结Unicode值的字符串中的前五个字符是一个好主意(假设它有五个,否则停止在那里结束)。 那会是一个好主意,还是坏事呢?
我在Java中这样做,但我无法想象这将使多大的差别。
通常哈希不会做算术,否则stop
和pots
将具有相同的哈希值。
你不会限制它的前n个字符,否则房子和房子将具有相同的哈希值。
一般来说hashs取值和一个素数相乘(使得它更容易产生独特的哈希值),所以,你可以这样做:
int hash = 7;
for (int i = 0; i < strlen; i++) {
hash = hash*31 + charAt(i);
}
如果它是一个安全的事情,你可以使用Java加密:
import java.security.MessageDigest;
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(stringToEncrypt.getBytes());
String encryptedString = new String(messageDigest.digest());
你或许应该使用String.hashCode() 。
如果你真的想实现自己的hashCode:
不要试图从哈希码的计算中排除的对象的显著部分来提高性能 - 约书亚布洛赫有效的Java
只使用前五个字符是一个坏主意 。 想想层次名称,如URL:他们都将有相同的散列码(因为他们都开始以“http://”,这意味着它们被存储在一个哈希表一样斗下,表现出可怕的性能。
以下是转述从“字符串的hashCode战争故事有效的Java ”:
在之前1.2至多16个字符所检查的所有版本中实现的字符串的散列函数,均匀分布在整个串间隔,开始与第一个字符。 对于大的集合层次名称的,如URL,这个哈希函数显示可怕的行为。
如果你是在Java中这样做那么你为什么这样做呢? 只需拨打.hashCode()
的字符串
番石榴的HashFunction
( Javadoc中 )提供体面的非加密散列强。
由尼克·本功能是好的,但如果你使用新的字符串(字节[]字节)进行改造字符串,它失败了。 您可以使用此功能来做到这一点。
private static final char[] hex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static String byteArray2Hex(byte[] bytes) {
StringBuffer sb = new StringBuffer(bytes.length * 2);
for(final byte b : bytes) {
sb.append(hex[(b & 0xF0) >> 4]);
sb.append(hex[b & 0x0F]);
}
return sb.toString();
}
public static String getStringFromSHA256(String stringToEncrypt) throws NoSuchAlgorithmException {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(stringToEncrypt.getBytes());
return byteArray2Hex(messageDigest.digest());
}
可能这可以帮助别人
// djb2 hash function
unsigned long hash(unsigned char *str)
{
unsigned long hash = 5381;
int c;
while (c = *str++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
源 后面djb2散列函数逻辑- SO
FNV-1被传言是字符串好的哈希函数。
对于长字符串(长于,比方说,约200字),你可以得到很好的表现出来的的MD4散列函数。 作为一种加密功能,它是大约15年前被打破,但对于非加密的目的,还是很不错的,而且出奇的快。 在Java的情况下,你将不得不在16位转换char
值转换为32位字,例如,通过这样的值分组到对。 Java中的快速实现MD4的可以发现sphlib 。 可能是矫枉过正的教室转让的情况下,但在其他方面值得一试。
如果你想看到的行业标准的实施,我想看看java.security.MessageDigest中 。
“消息摘要是采用任意大小的数据,并输出一个固定长度的散列值安全单向散列函数。”
SDBM:这个算法是为SDBM创建(NDBM的公共领域重新实现)数据库库
static unsigned long sdbm(unsigned char *str)
{
unsigned long hash = 0;
int c;
while (c = *str++)
hash = c + (hash << 6) + (hash << 16) - hash;
return hash;
}
这里有一个链接 ,说明许多不同的散列函数,现在我希望为自己的特定问题的ELF散列函数。 它输入任意长度的字符串。
public String hashString(String s) throws NoSuchAlgorithmException {
byte[] hash = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
hash = md.digest(s.getBytes());
} catch (NoSuchAlgorithmException e) { e.printStackTrace(); }
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.length; ++i) {
String hex = Integer.toHexString(hash[i]);
if (hex.length() == 1) {
sb.append(0);
sb.append(hex.charAt(hex.length() - 1));
} else {
sb.append(hex.substring(hex.length() - 2));
}
}
return sb.toString();
}
这将避免任何碰撞,这将是快速的,直到我们使用的计算换挡。
int k = key.length();
int sum = 0;
for(int i = 0 ; i < k-1 ; i++){
sum += key.charAt(i)<<(5*i);
}
它是一个好主意,试图开发串一个良好的事呢功能时与奇数工作。 此功能需要一个字符串,并返回一个索引值,到目前为止,它的工作相当不错。 而且具有更少的碰撞。 该指数范围从0 - 300,也许比这还要多,但我还没有得到任何提高,到目前为止,即使像“机电工程”长字
int keyHash(string key)
{
unsigned int k = (int)key.length();
unsigned int u = 0,n = 0;
for (Uint i=0; i<k; i++)
{
n = (int)key[i];
u += 7*n%31;
}
return u%139;
}
可以做的另一件事是通过索引乘以每个字符INT解析,因为它增加之类的词“熊”(0 * B)+(1 * E)+(2 * A)+(3 * R),这将给你一个int值一起玩。 上述第一哈希函数的碰撞“这里”和“听”,但仍有很大的给一些好的唯一值。 在下面的一个不是以“在这里”发生碰撞,“听”,因为我乘每个字符与索引,因为它增加。
int keyHash(string key)
{
unsigned int k = (int)key.length();
unsigned int u = 0,n = 0;
for (Uint i=0; i<k; i++)
{
n = (int)key[i];
u += i*n%31;
}
return u%139;
}
下面是我使用的哈希表我建立了一个简单的哈希函数。 它基本上是把文本文件,并存储每个字在表示字母顺序排列的索引。
int generatehashkey(const char *name)
{
int x = tolower(name[0])- 97;
if (x < 0 || x > 25)
x = 26;
return x;
}
这是什么通常做的就是词是按照他们的第一个字母的散列。 所以,与单词“A”将得到的0散列键,“B”会得到1等和“Z”将是25.数字和符号将具有26散列键开始存在的优点,这提供; 您可以轻松快速地计算出该商品的特定词将在哈希表中,因为它的一切都在按字母顺序索引的,这样的事情:代码可以在这里找到: https://github.com/abhijitcpatil/general
让下面的文字输入:阿提库斯到杰姆说有一天,“我宁愿你出手在后院锡罐,但我知道鸟后你会去。 拍摄所有你想要的蓝鸟,如果你可以打他们,但是请记住这是一种罪过杀死一只知更鸟。”这是我听到过的唯一一次阿提库斯说这是一种罪过做一些事情,我问Maudie小姐约它。 “你父亲是对的,”她说。 “Mockingbirds不做一两件事,除了化妆音乐让我们享受。 他们不要吃了人们的花园,不要窝在玉米婴儿床,他们没有做一两件事,但唱他们的心我们。 这就是为什么它是一种罪过杀死一只知更鸟。
这将是输出:
0 --> a a about asked and a Atticus a a all after at Atticus
1 --> but but blue birds. but backyard
2 --> cribs corn can cans
3 --> do don’t don’t don’t do don’t do day
4 --> eat enjoy. except ever
5 --> for for father’s
6 --> gardens go
7 --> hearts heard hit
8 --> it’s in it. I it I it’s if I in
9 --> jays Jem
10 --> kill kill know
11 -->
12 --> mockingbird. music make Maudie Miss mockingbird.”
13 --> nest
14 --> out one one only one
15 --> people’s
16 --> 17 --> right remember rather
18 --> sin sing said. she something sin say sin Shoot shot said
19 --> to That’s their thing they They to thing to time the That to the the tin to
20 --> us. up us
21 -->
22 --> why was was want
23 -->
24 --> you you you’ll you
25 -->
26 --> “Mockingbirds ” “Your ‘em “I’d