Files
xsl-validator/docs/blake2b_hash_implementation.md

5.3 KiB

Blake2b-Hash-Implementierung für XML-Dateien

Übersicht

Diese Dokumentation beschreibt die Implementierung der automatischen blake2b-Hash-Berechnung für XML-Dateien in der XSL-Validator-Anwendung.

Funktionalität

Automatische Hash-Berechnung beim Projektladen

Beim Laden eines Projekts in der MainWindow-Klasse werden automatisch alle XML-Dateien auf fehlende hashsum-Eigenschaften geprüft. Für Dateien ohne Hash-Wert wird dieser asynchron im Hintergrund berechnet.

Hash-Algorithmus

  • Algorithmus: blake2b (aus Python's hashlib)
  • Präfix: blake2b:
  • Format: blake2b:<64-stelliger-hex-hash>

Beispiel

blake2b:c0d6043a79e953f31921a68f008d20ef3bce5bc7f9613d0f53c3a3d3f0a5879e4a18b955f1741ddf190cf7769c1be47d4cf48246f455fa9f84e6599ce5b45119

Technische Implementierung

Erweiterte XmlFile-Klasse

Die conf.XmlFile-Klasse wurde um die optionale hashsum-Eigenschaft erweitert:

class XmlFile(BaseModel):
    xml: Path
    hashsum: str | None = None  # Neue Eigenschaft

Asynchrone Hash-Berechnung

XmlHashCalculatorThread

Eine spezialisierte QThread-Klasse für die asynchrone Hash-Berechnung:

class XmlHashCalculatorThread(QThread):
    hash_calculated = pyqtSignal(object, str)
    calculation_finished = pyqtSignal(int, int)
    error_occurred = pyqtSignal(str, str)

Hauptmethoden:

  • _calculate_blake2b_hash(): Berechnet den blake2b-Hash einer Datei
  • run(): Hauptschleife für die asynchrone Verarbeitung

Integration in MainWindow

Automatischer Start:

def load_project_from_file(self, file_path: Path):
    # ... Projekt laden ...
    # Starte Hash-Berechnung für alle XML-Dateien
    self._start_xml_hash_calculation()

Kern-Methoden:

  • _start_xml_hash_calculation(): Startet die asynchrone Hash-Berechnung
  • _collect_all_xml_files(): Sammelt alle XML-Dateien rekursiv
  • _on_hash_calculated(): Signal-Handler für berechnete Hashes
  • _calculate_hash_for_xml_file(): Synchrone Hash-Berechnung für neue Dateien

Rekursive Datensammlung

Die Implementierung durchsucht rekursiv alle TreeNode- und XslFile-Strukturen:

def _collect_all_xml_files(self, node: TreeNode) -> list[XmlFile]:
    xml_files = []
    
    # Sammle XML-Dateien aus XSL-Dateien
    for xsl_file in node.xsl_files:
        xml_files.extend(xsl_file.xml_files)
    
    # Rekursiv durch Kindknoten
    for child in node.children:
        xml_files.extend(self._collect_all_xml_files(child))
    
    return xml_files

Verwendung

Automatische Hash-Berechnung

Die Hash-Berechnung erfolgt automatisch beim Laden von Projekten. Keine manuelle Intervention erforderlich.

Neue XML-Dateien

Beim Hinzufügen neuer XML-Dateien wird der Hash synchron berechnet:

def add_xml_file(self, xml_file: XmlFile):
    if xml_file.hashsum is None:
        xml_file.hashsum = self._calculate_hash_for_xml_file(xml_file)

Fehlerbehandlung

Nicht existierende Dateien

def _calculate_blake2b_hash(self, file_path: Path) -> str | None:
    try:
        if not file_path.exists():
            return None
        # ... Hash-Berechnung ...
    except Exception as e:
        self.error_occurred.emit(str(file_path), str(e))
        return None

Thread-Sicherheit

  • Verwendung von Qt-Signalen für Thread-Kommunikation
  • Keine direkten UI-Updates aus Worker-Thread
  • Graceful handling von Thread-Fehlern

Performance-Optimierung

Asynchrone Verarbeitung

  • Hash-Berechnung läuft im Hintergrund
  • UI bleibt responsiv während der Berechnung
  • Batch-Verarbeitung mehrerer Dateien

Selektive Berechnung

  • Nur Dateien ohne bestehende hashsum werden verarbeitet
  • Vermeidung redundanter Berechnungen
  • Effiziente Speichernutzung

Testen

Test-Skript

Ein umfassendes Test-Skript (test_hash_implementation.py) validiert:

  • Korrekte Hash-Berechnung
  • XmlFile-Modell-Funktionalität
  • Hash-Konsistenz
  • Fehlerbehandlung

Ausführung

uv run python test_hash_implementation.py

Wartung und Erweiterung

Hinzufügung neuer Hash-Algorithmen

Die Implementierung kann einfach erweitert werden:

def _calculate_hash(self, file_path: Path, algorithm: str = "blake2b") -> str | None:
    if algorithm == "blake2b":
        return self._calculate_blake2b_hash(file_path)
    elif algorithm == "sha256":
        return self._calculate_sha256_hash(file_path)
    # ... weitere Algorithmen

Konfiguration

Hash-Einstellungen können über die Anwendungskonfiguration gesteuert werden:

class HashConfig:
    algorithm: str = "blake2b"
    prefix_format: str = "{algorithm}:"
    async_calculation: bool = True

Bekannte Einschränkungen

  1. Dateigröße: Sehr große XML-Dateien können die Hash-Berechnung verlangsamen
  2. Netzwerk-Dateien: Dateien auf Netzlaufwerken werden möglicherweise langsamer verarbeitet
  3. Encoding: Binärer Dateizugriff für konsistente Hash-Berechnung

Changelog

Version 1.0.0

  • Initiale Implementierung der blake2b-Hash-Berechnung
  • Asynchrone Verarbeitung mit QThread
  • Integration in Projektlade-Prozess
  • Umfassende Fehlerbehandlung
  • Test-Suite für Validierung