-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
improve captcha solving mechanisms (#19)
* add solver callback mechanism * add PIL viewer for displaying captcha in CLI * remove rsbbs captcha viewer * bump version and fix dependencies --------- Co-authored-by: Pairman Guo <[email protected]>
- Loading branch information
1 parent
f807256
commit 04e6b35
Showing
6 changed files
with
82 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from PIL.ImageShow import Viewer, register as register_pil_imshow | ||
from PIL import Image | ||
|
||
|
||
def _image_to_ascii(img, size=(80, 16), invert_pallete=True): | ||
# convert image to ascii art for cli view | ||
# given char dimension 24*16, optimal sizes are | ||
# (80, 16) for xk, (80, 21) for rsbbs | ||
if invert_pallete: | ||
chs = '@&%QWNM0gB$#DR8mHXKAUbGOpV4d9h6Pkqwaxoenut1ivsz/*cr!+<>;=^:\'-.` ' | ||
else: | ||
chs = ' `.-\':^=;><+!rc*/zsvi1tuneoxawqkP6h9d4VpOGbUAKXHm8RD#$Bg0MNWQ%&@' | ||
w, h = size | ||
img.load() | ||
im = img.im.convert('L').resize((w, h)) | ||
return '\n'.join(''.join( | ||
chs[im[i] // 4] for i in range(y, y + w) | ||
) for y in range(0, w * h, w)) | ||
|
||
|
||
class _CliViewer(Viewer): | ||
def show(self, image: Image.Image, **options: Image.Any) -> int: | ||
print(_image_to_ascii(image)) | ||
# always attempt other viewers | ||
return False | ||
|
||
def register(): | ||
register_pil_imshow(_CliViewer, 0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,32 @@ | ||
class Processor: | ||
def __init__(self, img): | ||
self.img = img.convert('L') | ||
self.img_arr = self.img.load() | ||
self.paint() | ||
|
||
DX = [1, 0, -1, 0] | ||
DY = [0, 1, 0, -1] | ||
|
||
def paint(self): | ||
w, h = self.img.size | ||
visited = set() | ||
q = [] | ||
q.append((0, 0, 255)) | ||
while q: | ||
x, y, value = q.pop() | ||
if x < 0 or y < 0 or x >= w or y >= h or \ | ||
(x, y) in visited: | ||
continue | ||
visited.add((x, y)) | ||
for i in range(4): | ||
try: | ||
pixel = self.img_arr[x + self.DX[i], y + self.DY[i]] | ||
except IndexError: | ||
continue | ||
if abs(pixel - self.img_arr[x, y]) > 5: | ||
q.append((x + self.DX[i], y + self.DY[i], 255 - value)) | ||
else: | ||
q.append((x + self.DX[i], y + self.DY[i], value)) | ||
self.img_arr[x, y] = value | ||
|
||
|
||
def _process_vcode(img): | ||
p = Processor(img) | ||
return p.img | ||
from base64 import b64decode | ||
from typing import Callable | ||
from io import BytesIO | ||
from PIL import Image | ||
|
||
|
||
def _default_solver(data): | ||
Image.open(BytesIO(data)).show() | ||
return input('验证码: ') | ||
|
||
|
||
def _ids_solver(data): | ||
# data is { | ||
# 'bigImage': ..., # 背景图(base64) | ||
# 'smallImage': ..., # 滑块图(base64) | ||
# 'tagWidth": 93, # 无用, 恒93 | ||
# 'yHeight': 0 # 无用, 恒0 | ||
# } | ||
img = Image.open(BytesIO(b64decode(data['bigImage']))) | ||
img.show() | ||
|
||
# 输入背景图左侧到滑块目标位置左侧的宽度 | ||
return int(input('滑块位移: ')) * 280 // img.width | ||
|
||
|
||
_solvers = { | ||
'ids.xidian.edu.cn': _ids_solver, | ||
} | ||
|
||
|
||
def get_solver(key) -> Callable: | ||
return _solvers.get(key, _default_solver) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
|
||
setuptools.setup( | ||
name="libxduauth", | ||
version="1.8.2", | ||
version="1.9.0", | ||
author="Frank", | ||
author_email="[email protected]", | ||
description="login utilities for XDU", | ||
|
@@ -19,7 +19,7 @@ | |
], | ||
python_requires='>=3.7', | ||
install_requires=[ | ||
"requests", "bs4", "pycryptodome", | ||
"requests", "bs4", "pycryptodome", "lxml", | ||
"importlib-resources", "Pillow", | ||
], | ||
) |