1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! Pure text utilities for the reCAPTCHA audio solver: normalise an STT
//! transcript for the answer field, recognise the rate-limit interstitial, and
//! validate an audio-clip URL. Re-exported at `captchaforge::solver::*` (the
//! doctests pin that public path), so moving them here is path-transparent.
use RATE_LIMIT_PHRASES;
/// Normalise an STT transcript for typing into the audio-response field.
///
/// reCAPTCHA's audio answers are space-separated words/digits; STT
/// engines love to add capitalisation and trailing punctuation. The
/// response field is matched case-insensitively but stray punctuation
/// counts as wrong characters.
///
/// # Examples
///
/// ```
/// use captchaforge::solver::clean_transcript;
/// assert_eq!(clean_transcript(" Hello, World. "), "hello world");
/// assert_eq!(clean_transcript("five seven, nine!"), "five seven nine");
/// assert_eq!(clean_transcript("\nthree\tfour\n"), "three four");
/// assert_eq!(clean_transcript(""), "");
/// ```
/// True when `text` matches a known reCAPTCHA rate-limit interstitial.
///
/// # Examples
///
/// ```
/// use captchaforge::solver::is_rate_limited;
/// assert!(is_rate_limited(
/// "Your computer or network may be sending automated queries"
/// ));
/// assert!(is_rate_limited("please TRY AGAIN LATER"));
/// assert!(!is_rate_limited("Press PLAY to listen"));
/// ```
/// True when `s` is a plausible reCAPTCHA audio MP3 URL. Non-empty,
/// http(s), and either the recaptcha host or a `.mp3` suffix.
///
/// # Examples
///
/// ```
/// use captchaforge::solver::looks_like_audio_url;
/// assert!(looks_like_audio_url(
/// "https://www.google.com/recaptcha/api2/payload?p=clip.mp3"
/// ));
/// assert!(looks_like_audio_url("http://cdn.example.com/x.mp3"));
/// assert!(!looks_like_audio_url(""));
/// assert!(!looks_like_audio_url("data:audio/mpeg;base64,abc"));
/// assert!(!looks_like_audio_url("blob:https://x"));
/// ```