This page documents the data structures and result types used throughout PDF-PyCrack.
All cracking operations return one of these result types:
::: pdf_pycrack.models.cracking_result options: show_source: true show_root_heading: true show_root_toc_entry: false heading_level: 3
Returned when a password is successfully discovered:
@dataclass
class PasswordFound:
password: str # The discovered password
passwords_tested: int # Number of passwords tested
duration: float # Time taken in seconds
rate: float # Passwords per second
memory_usage: float # Peak memory usage in MB
Example:
if isinstance(result, PasswordFound):
print(f"Password: '{result.password}'")
print(f"Found after testing {result.passwords_tested:,} passwords")
print(f"Rate: {result.rate:,.0f} passwords/second")
print(f"Duration: {result.duration:.2f} seconds")
Returned when all possible combinations have been exhausted:
@dataclass
class PasswordNotFound:
passwords_tested: int # Total passwords tested
duration: float # Time taken in seconds
rate: float # Average passwords per second
memory_usage: float # Peak memory usage in MB
Returned when the PDF file is not encrypted:
@dataclass
class NotEncrypted:
message: str = "PDF is not encrypted"
Returned when there’s an issue reading the PDF file:
@dataclass
class FileReadError:
error: str # Description of the error
suggested_action: str # What the user should do
Common errors:
Returned when the cracking process is interrupted:
@dataclass
class CrackingInterrupted:
passwords_tested: int # Passwords tested before interruption
duration: float # Time before interruption
reason: str # Why it was interrupted
Raised when there’s an error during initialization:
@dataclass
class InitializationError:
error: str # Description of the initialization error
suggested_action: str # What the user should do
Raised when the PDF file is corrupted or invalid:
@dataclass
class PDFCorruptedError:
error: str # Description of the corruption
suggested_action: str # What the user should do
Use isinstance()
to check result types:
from pdf_pycrack import crack_pdf_password, PasswordFound, PasswordNotFound
result = crack_pdf_password("file.pdf")
# Type checking
if isinstance(result, PasswordFound):
# Handle success
use_password(result.password)
elif isinstance(result, PasswordNotFound):
# Handle failure
try_different_parameters()
else:
# Handle errors
print(f"Error: {result}")
For type hints, you can use:
from typing import Union
from pdf_pycrack import CrackResult
def process_result(result: CrackResult) -> None:
"""Process a cracking result."""
if isinstance(result, PasswordFound):
print(f"Success: {result.password}")
# ... handle other types
All result types that include performance data have these fields:
Field | Type | Description |
---|---|---|
passwords_tested |
int |
Number of passwords attempted |
duration |
float |
Total time in seconds |
rate |
float |
Passwords per second |
memory_usage |
float |
Peak memory usage in MB |
Always check the result type before accessing specific fields:
result = crack_pdf_password("file.pdf")
# ✅ Good - check type first
if isinstance(result, PasswordFound):
print(result.password)
elif isinstance(result, FileReadError):
print(f"Error: {result.error}")
# ❌ Bad - assumes success
print(result.password) # AttributeError if not PasswordFound
import logging
def log_result(result: CrackResult) -> None:
"""Log the cracking result appropriately."""
if isinstance(result, PasswordFound):
logging.info(f"Password found: {result.password} "
f"({result.passwords_tested:,} attempts in {result.duration:.2f}s)")
elif isinstance(result, PasswordNotFound):
logging.warning(f"Password not found after {result.passwords_tested:,} attempts "
f"in {result.duration:.2f}s")
elif isinstance(result, FileReadError):
logging.error(f"File error: {result.error}")
else:
logging.error(f"Unexpected result: {result}")