Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve logic for extracting captchas #78

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,22 +351,25 @@ pub fn check_captcha_or_other<'a>(stdout: &'a str, flags: &'a Vec<String>) -> bo
}

// 利用正则表达式从信息中提取验证码
pub fn get_captchas(stdout: &str) -> Vec<String> {
// let re = Regex::new(r"\b[a-zA-Z0-9]{4,8}\b").unwrap(); // 只提取4-8位数字与字母组合
pub fn get_captchas(stdout: &str, keywords: &Vec<String>) -> Vec<String> {
let re = Regex::new(r"\b[a-zA-Z0-9][a-zA-Z0-9-]{2,6}[a-zA-Z0-9]\b").unwrap();
let stdout_str = stdout;
let mut captcha_vec = Vec::new();
for m in re.find_iter(stdout_str) {
for i in m.as_str().chars() {
if i.is_ascii_digit() {
captcha_vec.push(m.as_str().to_string());
break;
for m in re.find_iter(stdout) {
let captcha = m.as_str();
let captcha_start_index = m.start();
// 检查验证码前面的文本中是否包含关键词
let pre_text = &stdout[..captcha_start_index];
for keyword in keywords {
if pre_text.contains(keyword) {
captcha_vec.push(captcha.to_string());
break; // 找到关键词后就不再检查其他关键词
}
}
}
captcha_vec
}


// 如果检测到 chat.db 有变动,则提取最近一分钟内最新的一条信息
pub fn get_message_in_one_minute() -> String {
let output = Command::new("sqlite3")
Expand All @@ -380,8 +383,7 @@ pub fn get_message_in_one_minute() -> String {

// 如果信息中包含多个4-8位数字与字母组合(比如公司名称和验证码都是4-8位英文数字组合,例如CSDN)
// 则选取数字字符个数最多的的那个字串作为验证码
pub fn get_real_captcha(stdout: &str) -> String {
let captchas = get_captchas(stdout);
pub fn get_real_captcha(captchas: Vec<String>) -> String {
let mut real_captcha = String::new();
let mut max_digit_count = 0;
for captcha in captchas {
Expand Down Expand Up @@ -443,9 +445,9 @@ pub fn messages_thread() {
if captcha_or_other {
info!("{}", t!("new-verification-code-detected"));

let captchas = get_captchas(&stdout);
let captchas = get_captchas(&stdout, &flags);
info!("{}:{:?}", t!("all-possible-codes"), captchas);
let real_captcha = get_real_captcha(&stdout);
let real_captcha = get_real_captcha(captchas);
info!("{}:{:?}", t!("real-verification-code"), real_captcha);
let mut ctx = Clipboard::new().unwrap();
let old_clipboard_contents = get_old_clipboard_contents();
Expand Down Expand Up @@ -690,9 +692,9 @@ async fn async_watch<P: AsRef<Path>>(path: P) -> notify::Result<()> {
check_captcha_or_other(&content, &read_config().flags);
if is_captcha {
info!("{}", t!("new-verification-email-detected"));
let captchas = get_captchas(&content);
let captchas = get_captchas(&content, &read_config().flags);
info!("{}:{:?}", t!("all-possible-codes"), captchas);
let real_captcha = get_real_captcha(&content);
let real_captcha = get_real_captcha(captchas);
info!("{}:{:?}", t!("real-verification-code"), real_captcha);
let mut clpb = Clipboard::new().unwrap();

Expand Down
51 changes: 37 additions & 14 deletions tests/lib_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,67 +55,90 @@ fn test_check_captcha_or_other() {
#[test]
fn test_get_captchas() {
let stdout = "【自如网】自如验证码 356407, 请及时致电4001001111".to_string();
let captchas = get_captchas(&stdout);
let flags = vec![
"验证码".to_string(),
"动态密码".to_string(),
"verification".to_string(),
"code".to_string(),
"인증".to_string(),
"代码".to_string(),
];
let captchas = get_captchas(&stdout, &flags);
assert_eq!(captchas, vec!["356407".to_string()]);

let stdout =
"【百度账号】验证码:534571 。验证码提供他人可能导致百度账号被盗,请勿转发或泄漏。"
.to_string();
let captchas = get_captchas(&stdout);
let captchas = get_captchas(&stdout, &flags);
assert_eq!(captchas, vec!["534571".to_string()]);

let stdout = "【AIdea】您的验证码为:282443,请勿泄露于他人!".to_string();
let captchas = get_captchas(&stdout);
let captchas = get_captchas(&stdout, &flags);
assert_eq!(captchas, vec!["282443".to_string()]);

let stdout = "【必胜客】116352(动态验证码),请在30分钟内填写".to_string();
let captchas = get_captchas(&stdout);
let captchas = get_captchas(&stdout, &flags);
assert_eq!(captchas, vec!["116352".to_string()]);

let stdout =
"This output contains a captcha with non-alphanumeric characters: ABCD123".to_string();
let captchas = get_captchas(&stdout);
let captchas = get_captchas(&stdout, &flags);
assert_eq!(captchas, vec!["ABCD123".to_string()]);

let stdout = "[s1mple] your code is 123456".to_string();
let captchas = get_captchas(&stdout);
let captchas = get_captchas(&stdout, &flags);
assert_eq!(captchas, vec!["s1mple".to_string(), "123456".to_string()]);

let stdout = "您的验证码是12345,请勿泄露给他人。".to_string();
let captchas = get_captchas(&stdout);
let captchas = get_captchas(&stdout, &flags);
assert_eq!(captchas, vec!["12345".to_string()]);

let stdout = "您正在使用境外网上支付验证服务,动态密码为729729。动态密码连续输错3次,您的此次交易验证会失败。请勿向他人泄露![中国工商银行]。【工商银行】".to_string();
let captchas = get_captchas(&stdout);
let captchas = get_captchas(&stdout, &flags);
assert_eq!(captchas, vec!["729729".to_string()]);
}

#[test]
fn test_get_real_captcha() {
let flags = vec![
"验证码".to_string(),
"动态密码".to_string(),
"verification".to_string(),
"code".to_string(),
"인증".to_string(),
"代码".to_string(),
];

let stdout = String::from("【Microsoft】将123456用作Microsoft账户安全代码");
let result = get_real_captcha(&stdout);
let captchas = get_captchas(&stdout, &flags);
let result = get_real_captcha(captchas);
assert_eq!(result, "123456");

let stdout = String::from("【APPLE】Apple ID代码为:724818。请勿与他人共享。");
let result = get_real_captcha(&stdout);
let captchas = get_captchas(&stdout, &flags);
let result = get_real_captcha(captchas);
assert_eq!(result, "724818");

let stdout = String::from("【自如网】自如验证码 356407,有效时间为一分钟,请勿将验证码告知任何人!如非您本人操作,请及时致电4001001111");
let result = get_real_captcha(&stdout);
let captchas = get_captchas(&stdout, &flags);
let result = get_real_captcha(captchas);
assert_eq!(result, "356407");

let stdout = String::from(
"【腾讯云】验证码:134560,5分钟内有效,为了保障您的账户安全,请勿向他人泄漏验证码信息",
);
let result = get_real_captcha(&stdout);
let captchas = get_captchas(&stdout, &flags);
let result = get_real_captcha(captchas);
assert_eq!(result, "134560");

let stdout = String::from("Your confirmation code is below 一 enter it in your open browser window and we'll help you get signed in RKJ-YP6 If you didn't request this email, there's nothing to worry about - you can safely ignore it.");
let result = get_real_captcha(&stdout);
let captchas = get_captchas(&stdout, &flags);
let result = get_real_captcha(captchas);
assert_eq!(result, "RKJ-YP6");

let stdout = String::from("If this was you, your verification code is: 047289 If you didn't request i: click here to deny.");
let result = get_real_captcha(&stdout);
let captchas = get_captchas(&stdout, &flags);
let result = get_real_captcha(captchas);
assert_eq!(result, "047289");
}

Expand Down