CodeGym /Kurse /Python SELF DE /Hash-Funktionen und ihre Anwendung

Hash-Funktionen und ihre Anwendung

Python SELF DE
Level 54 , Lektion 5
Verfügbar

10.1 Einführung in Hash-Funktionen und Hash-Tabellen

Lass uns unser Verständnis von Hash-Funktionen und -Tabellen auffrischen und vertiefen. Eine Hash-Funktion ist ein Algorithmus, der Eingangsdaten variabler Länge in eine Zeichenkette fester Länge umwandelt. Wesentliche Eigenschaften von Hash-Funktionen:

  • Determinismus: Gleiche Eingangsdaten führen immer zum gleichen Ergebnis.
  • Schnelle Berechnung: Der Hash sollte schnell berechnet werden können.
  • Unumkehrbarkeit (für kryptografische Hash-Funktionen): Es ist unmöglich (oder sehr schwierig), die Ausgangsdaten aus dem Hash wiederherzustellen.
  • Gleichmäßige Verteilung: Kleine Änderungen in den Eingangsdaten führen zu erheblichen Änderungen im Hash.

Vereinfacht gesagt, bei identischen Objekten ist der Hash-Wert identisch, aber wenn die Hash-Funktion bei zwei Objekten übereinstimmt, müssen diese Objekte nicht unbedingt gleich sein. In der Mathematik nennt man das eine notwendige, aber nicht hinreichende Bedingung.

Eine Hash-Tabelle ist eine Datenstruktur, die eine Hash-Funktion nutzt, um Informationen effizient zu speichern und abzurufen. Sie besteht aus:

  • Einem Array von "Buckets" zum Speichern der Daten.
  • Einer Hash-Funktion, die bestimmt, in welchen Bucket die Daten gelegt werden.

Hash-Tabellen bieten schnellen Datenzugriff, üblicherweise mit einer Komplexität von O(1) im Durchschnittsfall.

Anwendung von Hash-Funktionen im echten Leben

Beispiel: Blockchain-Technologien

In Blockchains werden Hash-Funktionen verwendet, um einzigartige Block-IDs zu erstellen und die Datenintegrität sicherzustellen. Jeder Block enthält den Hash des vorherigen Blocks, was eine Kette schafft und das System resistent gegen Änderungen macht.


import hashlib
import time

class Block:
    def __init__(self, data, previous_hash):
        self.timestamp = time.time()
        self.data = data
        self.previous_hash = previous_hash
        self.hash = self.calculate_hash()

    def calculate_hash(self):
        hash_string = str(self.timestamp) + str(self.data) + str(self.previous_hash)
        return hashlib.sha256(hash_string.encode()).hexdigest()

# Beispiel der Verwendung
block1 = Block("Transaktion 1", "0")
block2 = Block("Transaktion 2", block1.hash)
print(f"Hash von Block 1: {block1.hash}")
print(f"Hash von Block 2: {block2.hash}")

Leistungsvergleich

Betrachten wir die Aufgabe, Duplikate in einem Array zu finden. Wir vergleichen die Lösung mit und ohne Verwendung einer Hash-Tabelle:


import time

def find_duplicates_with_hash(arr):
    seen = set()
    duplicates = []
    for item in arr:
        if item in seen:
            duplicates.append(item)
        else:
            seen.add(item)
    return duplicates

def find_duplicates_without_hash(arr):
    duplicates = []
    for i in range(len(arr)):
        for j in range(i+1, len(arr)):
            if arr[i] == arr[j] and arr[i] not in duplicates:
                duplicates.append(arr[i])
    return duplicates

# Leistungstest
arr = list(range(10000)) + list(range(5000))  # Array mit Duplikaten

start = time.time()
find_duplicates_with_hash(arr)
end = time.time()
print(f"Ausführungszeit mit Hash-Tabelle: {end - start} Sekunden")

start = time.time()
find_duplicates_without_hash(arr)
end = time.time()
print(f"Ausführungszeit ohne Hash-Tabelle: {end - start} Sekunden")

Führe das Programm aus und sieh selbst, wie der Einsatz einer Hash-Tabelle die Suche nach Duplikaten beschleunigt. Besonders bei großen Datenmengen.

10.2 Beispiele für die Anwendung von Hash-Funktionen in realen Aufgaben

1. Hashing von Passwörtern

Hash-Funktionen werden für die sichere Speicherung von Passwörtern verwendet. Statt Passwörter im Klartext zu speichern, speichern Systeme deren Hash-Werte. Bei der Eingabe eines Passworts durch den Nutzer wird das eingegebene Passwort gehasht und mit dem in der Datenbank gespeicherten Hash verglichen.

Implementierungsbeispiel:


import hashlib

def hash_password(password):
    return hashlib.sha256(password.encode()).hexdigest()

# Beispiel der Verwendung:
password = "securepassword"
hashed_password = hash_password(password)
print(f"Hash des Passworts: {hashed_password}")

2. Kontrolle der Datenintegrität

Hash-Funktionen werden verwendet, um die Integrität von Dateien und Daten zu überprüfen, z. B. um sicherzustellen, dass eine Datei während der Übertragung nicht verändert oder beschädigt wurde.

Implementierungsbeispiel:


import hashlib

def get_file_hash(file_path):
    hasher = hashlib.sha256()
    with open(file_path, 'rb') as file:
        buf = file.read()
        hasher.update(buf)
    return hasher.hexdigest()

# Beispiel der Verwendung:
file_hash = get_file_hash('example.txt')
print(f"SHA-256 Hash der Datei: {file_hash}")

3. Suchmaschinen und Indexierung

Suchmaschinen verwenden Hash-Funktionen, um Indizes zu erstellen und Informationen schnell zu finden. Jedes Dokument wird nach Schlüsselwörtern indexiert, und Hash-Funktionen helfen dabei, Dokumente, die bestimmte Wörter enthalten, schnell zu finden.

Implementierungsbeispiel:


def create_index(text):
    index = {}
    words = text.split()
    for word in words:
        word_hash = hash(word)
        if word_hash not in index:
            index[word_hash] = []
        index[word_hash].append(word)
    return index

# Beispiel der Verwendung:
text = "This is an example text for indexing"
index = create_index(text)
print(f"Index: {index}")

10.3 Optimierung der Suche mit Hash-Funktionen

1. Verwendung von Hash-Tabellen zur Duplikatsuche

Hash-Tabellen ermöglichen es, Duplikate in einem Array schnell zu finden, indem die Hash-Werte der Elemente verglichen werden.

Implementierungsbeispiel:


def find_duplicates(arr):
    seen = set()
    duplicates = []
    for item in arr:
        if item in seen:
            duplicates.append(item)
        else:
            seen.add(item)
    return duplicates

# Beispiel der Verwendung:
arr = [1, 2, 3, 2, 4, 5, 6, 4, 7]
print(find_duplicates(arr))  # Ausgabe: [2, 4]

2. Optimierung der Paarsuche mit bestimmter Summe

Hash-Tabellen ermöglichen es, Paare von Zahlen in einem Array effizient zu finden, deren Summe einem bestimmten Wert entspricht.

Implementierungsbeispiel:


def find_pairs_with_sum(arr, target_sum):
    seen = set()
    pairs = []

    for num in arr:
        complement = target_sum - num
        if complement in seen:
            pairs.append((complement, num))
        seen.add(num)

    return pairs

# Beispiel der Verwendung:
arr = [2, 4, 3, 7, 8, -2, 10, -1]
target_sum = 6
print(find_pairs_with_sum(arr, target_sum))  # Ausgabe: [(4, 2), (3, 3), (8, -2)]

10.4 Beispiele der Verwendung von Hash-Funktionen in verschiedenen Algorithmen

1. Zählen der Wortanzahl in einem Text

Verwende eine Hash-Tabelle, um die Anzahl der Vorkommen jedes Wortes in einem Text zu zählen.

Implementierungsbeispiel:


def count_words(text):
    word_count = {}
    words = text.split()

    for word in words:
        if word in word_count:
            word_count[word] += 1
        else:
            word_count[word] = 1

    return word_count

# Beispiel der Verwendung:
text = "this is a test this is only a test"
print(count_words(text))  # Ausgabe: {'this': 2, 'is': 2, 'a': 2, 'test': 2, 'only': 1}

2. Überprüfung der Schnittmenge von zwei Arrays

Überprüfe, ob zwei Arrays eine Schnittmenge haben (ob sie mindestens ein gemeinsames Element haben).

Implementierungsbeispiel:


def has_intersection(arr1, arr2):
    set1 = set(arr1)
    for item in arr2:
        if item in set1:
            return True
    return False

# Beispiel der Verwendung:
arr1 = [1, 2, 3, 4]
arr2 = [3, 5, 6, 7]
arr3 = [8, 9, 10]
print(has_intersection(arr1, arr2))  # Ausgabe: True
print(has_intersection(arr1, arr3))  # Ausgabe: False

3. Überprüfung der Einzigartigkeit von Elementen in einem Array

Überprüfe, ob ein Array nur einzigartige Elemente enthält.

Implementierungsbeispiel:


def all_unique(arr):
    seen = set()
    for item in arr:
        if item in seen:
            return False
        seen.add(item)
    return True

# Beispiel der Verwendung:
arr1 = [1, 2, 3, 4, 5]
arr2 = [1, 2, 3, 4, 5, 3]
print(all_unique(arr1))  # Ausgabe: True
print(all_unique(arr2))  # Ausgabe: False
1
Umfrage/Quiz
Hashing, Level 54, Lektion 5
Nicht verfügbar
Hashing
Hashing
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION