programing

문자열에 적합한 해시 함수

kingscode 2022. 7. 13. 00:08
반응형

문자열에 적합한 해시 함수

현의 해시함수를 생각해내려고 노력 중이야.그리고 문자열의 처음 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;
}

원천 djb2 해시함수의 배후에 있는 논리(SO)

업계 표준의 실장을 참조하려면 , 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

반응형