Added code for practical-1.2, i.e. captcha image.
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
# CSDF - Practical-1 (Email Header Analysis)
|
||||
|
||||
"""
|
||||
THIS CODE HAS BEEN TESTED AND IS FULLY OPERATIONAL.
|
||||
|
||||
Problem Statement: CAPTCHA image - Implement a program to generate and verify CAPTCHA image.
|
||||
|
||||
Code from CyberSecurityAndDigitalForensics (SPPU - Final Year - Computer Engineering - Content) repository on KSKA Git: https://git.kska.io/sppu-be-comp-content/CyberSecurityAndDigitalForensics
|
||||
"""
|
||||
|
||||
# BEGINNING OF CODE
|
||||
import random
|
||||
import string
|
||||
from captcha.image import ImageCaptcha
|
||||
from PIL import Image
|
||||
import hashlib
|
||||
import time
|
||||
import os
|
||||
|
||||
class CaptchaManager:
|
||||
"""
|
||||
A comprehensive CAPTCHA generation and verification system
|
||||
"""
|
||||
|
||||
def __init__(self, length=6, width=280, height=90):
|
||||
"""
|
||||
Initialize the CAPTCHA manager
|
||||
|
||||
Args:
|
||||
length: Number of characters in CAPTCHA
|
||||
width: Image width in pixels
|
||||
height: Image height in pixels
|
||||
"""
|
||||
self.length = length
|
||||
self.image_captcha = ImageCaptcha(width=width, height=height)
|
||||
self.captcha_store = {} # Store CAPTCHA with expiry time
|
||||
self.expiry_time = 180 # 3 minutes in seconds
|
||||
|
||||
def generate_captcha_text(self):
|
||||
"""
|
||||
Generate random CAPTCHA text
|
||||
|
||||
Returns:
|
||||
String of random alphanumeric characters
|
||||
"""
|
||||
characters = string.ascii_uppercase + string.digits
|
||||
# Exclude ambiguous characters like 0, O, I, 1
|
||||
characters = characters.replace('0', '').replace('O', '').replace('I', '').replace('1', '')
|
||||
captcha_text = ''.join(random.choice(characters) for _ in range(self.length))
|
||||
return captcha_text
|
||||
|
||||
def generate_captcha_image(self, captcha_text=None, filename='captcha.png'):
|
||||
"""
|
||||
Generate CAPTCHA image
|
||||
|
||||
Args:
|
||||
captcha_text: Text to display (auto-generated if None)
|
||||
filename: Output filename
|
||||
|
||||
Returns:
|
||||
Tuple of (captcha_text, session_id, filename)
|
||||
"""
|
||||
if captcha_text is None:
|
||||
captcha_text = self.generate_captcha_text()
|
||||
|
||||
# Generate image
|
||||
data = self.image_captcha.generate(captcha_text)
|
||||
self.image_captcha.write(captcha_text, filename)
|
||||
|
||||
# Create session ID
|
||||
session_id = hashlib.md5(
|
||||
f"{captcha_text}{time.time()}".encode()
|
||||
).hexdigest()
|
||||
|
||||
# Store CAPTCHA with expiry time
|
||||
self.captcha_store[session_id] = {
|
||||
'text': captcha_text,
|
||||
'timestamp': time.time()
|
||||
}
|
||||
|
||||
return captcha_text, session_id, filename
|
||||
|
||||
def verify_captcha(self, session_id, user_input):
|
||||
"""
|
||||
Verify user's CAPTCHA input
|
||||
|
||||
Args:
|
||||
session_id: Unique session identifier
|
||||
user_input: User's input text
|
||||
|
||||
Returns:
|
||||
Dictionary with verification result
|
||||
"""
|
||||
# Check if session exists
|
||||
if session_id not in self.captcha_store:
|
||||
return {
|
||||
'success': False,
|
||||
'message': 'Invalid session or CAPTCHA expired'
|
||||
}
|
||||
|
||||
captcha_data = self.captcha_store[session_id]
|
||||
current_time = time.time()
|
||||
|
||||
# Check expiry
|
||||
if current_time - captcha_data['timestamp'] > self.expiry_time:
|
||||
del self.captcha_store[session_id]
|
||||
return {
|
||||
'success': False,
|
||||
'message': 'CAPTCHA expired. Please try again.'
|
||||
}
|
||||
|
||||
# Verify CAPTCHA (case-insensitive)
|
||||
if user_input.upper() == captcha_data['text'].upper():
|
||||
del self.captcha_store[session_id] # Remove after successful verification
|
||||
return {
|
||||
'success': True,
|
||||
'message': 'CAPTCHA verified successfully!'
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'success': False,
|
||||
'message': 'Incorrect CAPTCHA. Please try again.'
|
||||
}
|
||||
|
||||
def cleanup_expired(self):
|
||||
"""
|
||||
Remove expired CAPTCHAs from storage
|
||||
"""
|
||||
current_time = time.time()
|
||||
expired_sessions = [
|
||||
sid for sid, data in self.captcha_store.items()
|
||||
if current_time - data['timestamp'] > self.expiry_time
|
||||
]
|
||||
for sid in expired_sessions:
|
||||
del self.captcha_store[sid]
|
||||
|
||||
|
||||
# Alternative simple implementation using Pillow
|
||||
class SimpleCaptcha:
|
||||
"""
|
||||
Simple CAPTCHA implementation using Pillow
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def generate(length=6):
|
||||
"""
|
||||
Generate simple CAPTCHA with noise
|
||||
|
||||
Returns:
|
||||
Tuple of (captcha_text, Image object)
|
||||
"""
|
||||
from PIL import ImageDraw, ImageFont
|
||||
|
||||
# Generate random text
|
||||
chars = ''.join(random.choice(string.ascii_uppercase + string.digits)
|
||||
for _ in range(length))
|
||||
|
||||
# Create image
|
||||
img = Image.new('RGB', (200, 100), color=(73, 109, 137))
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
# Try to load a font, fallback to default if not available
|
||||
try:
|
||||
font = ImageFont.truetype('arial.ttf', 36)
|
||||
except:
|
||||
font = ImageFont.load_default()
|
||||
|
||||
# Draw characters with random positions
|
||||
x = 20
|
||||
for char in chars:
|
||||
y = random.randint(25, 35)
|
||||
draw.text((x, y), char, font=font, fill=(255, 255, 0))
|
||||
x += 30
|
||||
|
||||
# Add noise (dots)
|
||||
for _ in range(150):
|
||||
x = random.randint(0, 200)
|
||||
y = random.randint(0, 100)
|
||||
draw.point((x, y), fill=(random.randint(0, 255),
|
||||
random.randint(0, 255),
|
||||
random.randint(0, 255)))
|
||||
|
||||
# Add lines for distortion
|
||||
for _ in range(5):
|
||||
start = (random.randint(0, 200), random.randint(0, 100))
|
||||
end = (random.randint(0, 200), random.randint(0, 100))
|
||||
draw.line([start, end], fill=(255, 255, 255), width=1)
|
||||
|
||||
return chars, img
|
||||
|
||||
|
||||
# Example usage and testing
|
||||
def main():
|
||||
"""
|
||||
Demonstration of CAPTCHA generation and verification
|
||||
"""
|
||||
print("=== CAPTCHA Generation and Verification Demo ===\n")
|
||||
|
||||
# Initialize CAPTCHA manager
|
||||
manager = CaptchaManager(length=6)
|
||||
|
||||
# Generate CAPTCHA
|
||||
captcha_text, session_id, filename = manager.generate_captcha_image()
|
||||
print(f"CAPTCHA Generated: {captcha_text}")
|
||||
print(f"Session ID: {session_id}")
|
||||
print(f"Image saved as: {filename}\n")
|
||||
|
||||
# Simulate user input
|
||||
print("Verification Tests:")
|
||||
|
||||
# Test 1: Correct input
|
||||
result = manager.verify_captcha(session_id, captcha_text)
|
||||
print(f"Test 1 (Correct): {result}")
|
||||
|
||||
# Generate new CAPTCHA for next test
|
||||
captcha_text, session_id, _ = manager.generate_captcha_image('test_captcha_2.png')
|
||||
|
||||
# Test 2: Incorrect input
|
||||
result = manager.verify_captcha(session_id, "WRONG")
|
||||
print(f"Test 2 (Incorrect): {result}")
|
||||
|
||||
# Test 3: Invalid session
|
||||
result = manager.verify_captcha("invalid_session", "TEST")
|
||||
print(f"Test 3 (Invalid Session): {result}")
|
||||
|
||||
# Demonstrate simple CAPTCHA
|
||||
print("\n=== Simple CAPTCHA Demo ===")
|
||||
captcha_text, img = SimpleCaptcha.generate()
|
||||
img.save('simple_captcha.png')
|
||||
print(f"Simple CAPTCHA Text: {captcha_text}")
|
||||
print("Image saved as: simple_captcha.png")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
# END OF CODE
|
||||
Reference in New Issue
Block a user