문자열에 적합한 해시 함수
현의 해시함수를 생각해내려고 노력 중이야.그리고 문자열의 처음 5개 문자의 유니코드 값을 합산하는 것이 좋을 것 같습니다(다섯 글자가 있다고 가정하고, 그렇지 않으면 끝부분에서 멈춥니다).그게 좋은 생각일까요, 아니면 나쁜 생각일까요?
자바에서 하고 있습니다만, 큰 차이는 없을 것 같습니다.
계산을 않습니다 않으면 해시는 계산을 않습니다.stop
★★★★★★★★★★★★★★★★★」pots
는 같은 해시를 가집니다.
그리고 처음 n자로 제한하지 않습니다. 그렇지 않으면 집과 집이 동일한 해시를 가질 수 있기 때문입니다.
일반적으로 해시는 값을 가져와서 소수에 곱합니다(고유한 해시를 생성할 가능성이 높아집니다).이렇게 하면 다음과 같은 작업을 할 수 있습니다.
int hash = 7;
for (int i = 0; i < strlen; i++) {
hash = hash*31 + charAt(i);
}
보안에 관한 것이라면 Java crypto를 사용할 수 있습니다.
import java.security.MessageDigest;
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(stringToHash.getBytes());
String stringHash = new String(messageDigest.digest());
String.hashCode()를 사용해야 합니다.
hashCode를 직접 구현하는 경우:
성능 향상을 위해 개체의 중요한 부분을 해시 코드 계산에서 제외하려고 하지 마십시오. - Joshua Bloch, Effective Java
처음 5글자만 사용하는 것은 좋지 않습니다.URL과 같은 계층 이름에 대해 생각해 보십시오.모두 동일한 해시 코드를 가집니다(모두 "http://"로 시작하므로 해시 맵의 동일한 버킷에 저장되므로 성능이 저하됩니다).
String hashCode를 "Effective Java"에서 번역한 전쟁이야기는 다음과 같습니다.
1.2 이전의 모든 릴리스에서 구현된 String 해시 함수는 첫 번째 문자부터 시작하여 문자열 전체에 균일한 간격을 두고 최대 16자를 검사했습니다.URL 등의 계층 이름 집합의 경우 이 해시 함수는 끔찍한 동작을 보여줍니다.
바에서 는는 면면 ?? ??? 전화하세요..hashCode()
에 매단
Guava(javadoc)는 암호화 강도가 높지 않은 적절한 해시를 제공합니다.
Nick이 제공하는 이 함수는 좋지만 새로운 String(byte[]바이트)을 사용하여 String으로 변환하면 실패합니다.이 기능을 사용하여 실행할 수 있습니다.
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());
}
이게 누군가를 도울 수 있을지도 몰라
FNV-1은 문자열에 적합한 해시 함수라고 알려져 있습니다.
긴 문자열(예를 들어 약 200자 이상)의 경우 MD4 해시함수에서 뛰어난 성능을 얻을 수 있습니다.암호화 기능으로는 약 15년 전에 고장났지만, 암호화 이외의 목적으로는 매우 양호하고, 놀라울 정도로 빠릅니다.자바에서는 16비트를 변환해야 합니다.char
예를 들어 이러한 값을 쌍으로 그룹화하여 값을 32비트 단어로 만듭니다.Java에서의 MD4의 고속 실장은 sphlib에서 확인할 수 있습니다.아마도 교실 과제에서는 과잉 살상이겠지만, 그렇지 않으면 시도해 볼 가치가 있어요.
// 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;
}
업계 표준의 실장을 참조하려면 , 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;
}
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 해석에 인덱스를 곱하면 "bear" (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입니다.이것은 이 기능을 제공하는 장점입니다.해시 테이블에서 특정 단어가 색인되는 장소를 쉽고 빠르게 계산할 수 있습니다.모두 알파벳 순서로 되어 있기 때문입니다.이러한 코드는 다음 URL에서 찾을 수 있습니다.https://github.com/abhijitcpatil/general
다음 텍스트를 입력으로 제공:애티커스는 어느 날 젬에게 말했다. "나는 네가 뒷마당에서 깡통을 쏘고 싶지만, 나는 네가 새를 쫓을 것을 알고 있어.블루제이를 다 쏴라. 칠 수 있다면, 하지만 앵무새를 죽이는 것은 죄악이라는 것을 기억하라."애티커스가 뭔가를 하는 게 죄라고 말하는 걸 들은 건 그때뿐이었어요 그래서 마우디 양에게 물어봤죠"네 아빠 말이 맞아."라고 그녀가 말했다."새들은 우리가 즐길 수 있도록 음악을 만드는 것 외에는 아무것도 하지 않습니다.그들은 사람들의 정원을 먹어 치우지 않고, 옥수수 요람에 둥지를 틀지 않는다. 그들은 우리를 위해 애써 노래하는 것 외에는 아무것도 하지 않는다.그래서 흉내지빠귀를 죽이는게 죄야.
출력은 다음과 같습니다.
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
언급URL : https://stackoverflow.com/questions/2624192/good-hash-function-for-strings
'programing' 카테고리의 다른 글
VueJ 렌더링 기능을 사용하여 소품을 클래스에 전달하는 방법 (0) | 2022.07.13 |
---|---|
Vuex 스토어에서 작업을 디스패치하려고 하면 Nuxt가 '알 수 없는 작업 유형' 오류를 발생시킵니다. (0) | 2022.07.13 |
vue/vuex를 사용하여 입력에서 데이터를 필터링하려면 어떻게 해야 합니까? (0) | 2022.07.13 |
필터와 함께 Vue 템플릿에서 3진 연산자를 사용하는 방법 (0) | 2022.07.12 |
안드로이드용 애플리케이션을 C 또는 C++로 작성하시겠습니까? (0) | 2022.07.12 |