Slider CAPTCHA Mechanisms
Slider CAPTCHAs typically require users to drag a puzzle piece to its correct position on a background image. Automated solutions must reconstruct the original image from scrambled fragments and calculate the precise sliding distance.
Pkulaw Slider Implementation
import json
import random
import time
from io import BytesIO
from base64 import b64decode
from PIL import Image
import requests
from ddddocr import DdddOcr
class CaptchaSolver:
def __init__(self):
self.ocr = DdddOcr(det=False, ocr=False)
self.session = requests.Session()
self.session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'X-Requested-With': 'XMLHttpRequest'
})
def create_movement_pattern(self, total_distance):
"""Generate human-like mouse movement trajectory"""
movements = []
accumulated = 0
midpoint = total_distance * 0.75
interval = 0.2
velocity = 0
while accumulated < total_distance:
if accumulated < midpoint:
acceleration = random.uniform(1.5, 2.5)
else:
acceleration = -random.uniform(1.5, 2.5)
initial_vel = velocity
velocity = initial_vel + acceleration * interval
displacement = initial_vel * interval + 0.5 * acceleration * interval**2
accumulated += displacement
movements.append(round(displacement))
coordinates = []
current_pos = 0
for move in movements:
current_pos += move
timestamp = round(time.time() * 1000)
coordinates.append(f"{current_pos},{timestamp}")
time.sleep(0.004)
return '|'.join(coordinates)
def fetch_captcha_data(self):
"""Retrieve CAPTCHA image components"""
payload = {'act': 'getcode', 'spec': '300*200'}
response = self.session.post(
'https://www.pkulaw.com/VerificationCode/GetVerifiCodeResult',
data=payload
).json()
data = json.loads(response)
y_offset = data['y']
positions = data['array']
puzzle_piece = data['small']
with open('puzzle.jpg', 'wb') as f:
f.write(b64decode(puzzle_piece.split(',')[1]))
self.reconstruct_image(positions.split(','), b64decode(data['normal'].split(',')[1]))
def reconstruct_image(self, position_map, image_data):
"""Rebuild original image from scrambled fragments"""
scrambled_img = Image.open(BytesIO(image_data))
restored_img = Image.new("RGB", scrambled_img.size)
tile_size = 30
tile_height = 100
for index, pos in enumerate(position_map):
position = int(pos)
source_x = (index - 10) * tile_size if index > 9 else index * tile_size
source_y = tile_height if index > 9 else 0
tile = scrambled_img.crop((source_x, source_y, source_x + tile_size, source_y + tile_height))
dest_x = (position - 10) * tile_size if position > 9 else position * tile_size
dest_y = tile_height if position > 9 else 0
restored_img.paste(tile, (dest_x, dest_y))
restored_img.save('background.jpg')
def calculate_offset(self):
"""Determine required sliding distance"""
with open('background.jpg', 'rb') as bg_file, open('puzzle.jpg', 'rb') as puzzle_file:
bg_data = bg_file.read()
puzzle_data = puzzle_file.read()
result = self.ocr.slide_match(puzzle_data, bg_data, simple_target=True)
return result['target']
def submit_solution(self, distance):
"""Submit solved CAPTCHA response"""
payload = {
'act': 'check',
'point': str(distance),
'timespan': '1625',
'datelist': self.create_movement_pattern(distance)
}
response = self.session.post(
'https://www.pkulaw.com/VerificationCode/GetVerifiCodeResult',
data=payload
)
print(response.json())
def execute(self):
self.fetch_captcha_data()
offset = self.calculate_offset()
self.submit_solution(offset[0])
if __name__ == '__main__':
solver = CaptchaSolver()
solver.execute()
JD.com Slider Implementation
import json
import time
import random
from base64 import b64decode
import requests
import execjs
from ddddocr import DdddOcr
class JdCaptchaSolver:
def __init__(self):
self.session = requests.Session()
self.ocr = DdddOcr(ocr=False, det=False, show_ad=False)
def solve_jd_captcha(self, cookies):
"""Solve JD.com's slider CAPTCHA"""
self.session.cookies.update(cookies)
params = {
'appId': '1604ebb2287',
'scene': 'login',
'product': 'click-bind-suspend',
'e': cookies['3AB9D23F7A4B3C9B'],
'lang': 'zh_CN',
'callback': f'jsonp_{random.random()}'.replace('.', '')
}
response = requests.get('https://iv.jd.com/slide/g.html', params=params)
captcha_data = json.loads(response.text.split('(')[-1][:-1])
challenge_id = captcha_data['challenge']
puzzle_img = b64decode(captcha_data['patch'])
background_img = b64decode(captcha_data['bg'])
# Calculate sliding distance
match_result = self.ocr.slide_match(
target_bytes=puzzle_img,
background_bytes=background_img,
simple_target=True
)
pixel_distance = match_result['target'][0]
scaled_distance = int(pixel_distance * 278 / 360)
# Generate movement trajectory
movement_data = self.generate_trajectory(scaled_distance)
time.sleep(2)
# Load JavaScript encryption
js_engine = execjs.compile(open('encryption.js', 'r').read())
verification_params = {
'd': js_engine.call('encryptCoordinates', movement_data),
'c': challenge_id,
'w': '278',
'appId': '1604ebb2287',
's': '224271118108593154',
'callback': f'jsonp_{random.random()}'.replace('.', '')
}
result = self.session.get('https://iv.jd.com/slide/s.html', params=verification_params)
return result.text
def generate_trajectory(self, distance):
"""Generate movement coordinates"""
# Implementation varies by platform requirements
pass
Key Techniques
- Image Reconstruction: Reassembling scrambled image fragments to their original positions
- Distance Calculation: Using OCR tools to measure precise sliding distances
- Human-like Motion: Simulating natural mouse movement patterns
- Request Encryption: Handling platform-specific encryption mechanimss