Goede hash-functie voor strings

Ik probeer een goede hash-functie voor snaren te bedenken. En ik dacht dat het misschien een goed idee is om de Unicode-waarden samen te vatten voor de eerste vijf tekens in de tekenreeks (ervan uitgaande dat het vijf heeft, anders stop dan waar het eindigt). Zou dat een goed idee zijn, of is het een slechte?

Ik doe dit in Java, maar ik zou me niet voorstellen dat dat veel een verschil zou maken.


Antwoord 1, Autoriteit 100%

Meestal zouden hashes geen sommen doen, anders stopen potshebben dezelfde hash.

En u zou het niet beperken tot de eerste N-personages omdat anders huis en huizen dezelfde hash hebben.

Over het algemeen Hashs neemt de waarden en vermenigvuldig het door een priemgetal (maakt het waarschijnlijker unieke hashes), zodat u iets als:

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

Antwoord 2, Autoriteit 86%

Als het een beveiliging is, zou u Java Crypto kunnen gebruiken:

import java.security.MessageDigest;
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(stringToHash.getBytes());
String stringHash = new String(messageDigest.digest());

Antwoord 3, Autoriteit 22%

U moet waarschijnlijk string. hashcode () .

Als u zelf echt Hashcode wilt implementeren:

Laat niet worden verleid om uit te sluiten
significante delen van een object van
De HASH-code-berekening om te verbeteren
Prestaties – Jozua Bloch, effectieve Java

Het is een slecht ideeom alleen de eerste vijf tekens te gebruiken. Denk aan hiërarchische namen, zoals URL’s: ze hebben allemaal dezelfde hash-code (omdat ze allemaal beginnen met “http://”, wat betekent dat ze onder dezelfde bucket in een hash-map zijn opgeslagen en vreselijke prestaties vertonen.

Hier is een oorlogsverhaal geparafraseerd op de String hashCode van “Effectieve Java” :

De String hash-functie geïmplementeerd
in alle releases vóór 1.2 onderzocht
maximaal zestien tekens, gelijkmatig
verdeeld over de tekenreeks, beginnend met
met het eerste teken. voor grote
verzamelingen van hiërarchische namen,
zoals URL’s, deze hashfunctie
vertoonde vreselijk gedrag.


Antwoord 4, autoriteit 9%

Als je dit in Java doet, waarom doe je het dan? Roep gewoon .hashCode()aan op de string


Antwoord 5, autoriteit 7%

Guava’s HashFunction(javadoc) biedt fatsoenlijke niet -crypto-sterke hashing.


Antwoord 6, autoriteit 5%

Deze functie van Nick is goed, maar als je nieuwe String(byte[] bytes) gebruikt om de transformatie naar String uit te voeren, is het mislukt. U kunt deze functie daarvoor gebruiken.

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

Misschien kan dit iemand helpen


Antwoord 7, autoriteit 3%

FNV-1schijnt een goede hashfunctie voor strings te zijn.

Voor lange tekenreeksen (langer dan bijvoorbeeld ongeveer 200 tekens), kunt u goede prestaties halen uit de MD4hash-functie. Als cryptografische functie is het ongeveer 15 jaar geleden kapot gegaan, maar voor niet-cryptografische doeleinden is het nog steeds erg goed en verrassend snel. In de context van Java zou u de 16-bits char-waarden moeten converteren naar 32-bits woorden, b.v. door dergelijke waarden in paren te groeperen. Een snelle implementatie van MD4 in Java is te vinden in sphlib. Waarschijnlijk overkill in de context van een klassikale opdracht, maar verder het proberen waard.


Antwoord 8, autoriteit 2%

// 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;
}

bron
Logica achter djb2 hash-functie – SO


Antwoord 9, autoriteit 2%

Als je de implementaties van industriestandaarden wilt zien, kijk ik naar java.security.MessageDigest.

“Berichtsamenvattingen zijn veilige eenrichtings-hashfuncties die gegevens van willekeurige grootte nemen en een hash-waarde met een vaste lengte uitvoeren.”


Antwoord 10

sdbm:dit algoritme is gemaakt voor de databasebibliotheek van sdbm (een herimplementatie in het publieke domein van 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;
}

Antwoord 11

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

Antwoord 12

Dit voorkomt botsingen en gaat snel totdat we de verschuiving in berekeningen gebruiken.

int k = key.length();
    int sum = 0;
    for(int i = 0 ; i < k-1 ; i++){
        sum += key.charAt(i)<<(5*i);
    }

Antwoord 13

Het is een goed idee om met oneven getallen te werken als je een goede hast-functie voor string probeert te ontwikkelen. deze functie neemt een string en retourneert een indexwaarde, tot nu toe werkt het redelijk goed. en heeft minder botsingen. de index varieert van 0 – 300 misschien zelfs meer dan dat, maar ik ben tot nu toe niet hoger geworden, zelfs niet met lange woorden als “elektromechanica”

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;
}

een ander ding dat u kunt doen, is elk teken int parse vermenigvuldigen met de index terwijl het toeneemt zoals het woord “beer”
(0*b) + (1*e) + (2*a) + (3*r) waarmee je een int-waarde krijgt om mee te spelen. de eerste hash-functie hierboven botsen bij “hier” en “horen”, maar nog steeds geweldig in het geven van een aantal goede unieke waarden. die hieronder botst niet met “hier” en “hoor” omdat ik elk teken vermenigvuldig met de index als deze toeneemt.

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;
}

Antwoord 14

Hier is een eenvoudige hashfunctie die ik gebruik voor een hashtabel die ik heb gebouwd. Het is in feite voor het nemen van een tekstbestand en slaat elk woord op in een index die de alfabetische volgorde vertegenwoordigt.

int generatehashkey(const char *name)
{
        int x = tolower(name[0])- 97;
        if (x < 0 || x > 25)
           x = 26;
        return x;
}

Wat dit in feite doet is woorden gehashte op basis van hun eerste letter. Dus, woord beginnend met ‘a’ zou een hekje van 0 krijgen, ‘b’ zou krijgen 1 en zo verder en ‘z’ zou zijn 25. Cijfers en symbolen zou een hash sleutel van 26. hebben er een voordeel biedt dit ; U kunt eenvoudig en snel uitrekenen waar een bepaald woord zou worden geïndexeerd in de hash-tabel sinds zijn allen in een alfabetische volgorde, zoiets als dit:
Code is hier te vinden: https://github.com/abhijitcpatil/general

Het geven van de volgende tekst als input: Atticus zei tegen Jem op een dag: “Ik heb liever dat je beschoten blikjes in de achtertuin, maar ik weet dat je gaat
na vogels. Schiet alle Blue Jays je wilt, als je em kan raken’, maar
vergeet niet het is een zonde om een ​​mockingbird te doden.” Dat was de enige keer dat ik
ooit gehoord Atticus zeggen dat het een zonde is om iets te doen, en ik vroeg Miss
Maudie over. “Rechts van je vader,” zei ze. “Mockingbirds niet
een ding doen, behalve maken muziek voor ons te genieten. Ze hoeven niet opeten
mensen tuinen, doen niet nest in voor graan, ze niet een ding te doen
maar zingen hun hart uit voor ons. Daarom is het een zonde is om te doden
mockingbird.

Dit zou de output zijn:

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

Other episodes