reCAPTCHA思路展示

前言

图像选择挑战(Image Selection reCAPTCHA)
描述:当系统无法通过复选框确认用户身份时,会显示一个图像选择任务,要求用户从一组图片中选择符合特定条件的图片,例如“选择包含交通灯的图片”或“选择包含汽车的格子”。
例子:用户可能看到一个 3x3 的图片网格,要求点击包含指定对象的格子(例如街道标志、商店门面等)。有时需要多轮选择,直到系统确认用户为人类。
使用场景:用于需要更高安全性的场景,如防止机器人批量注册或提交垃圾信息。

流程分析

Protobuf–>一个数组–>分析每个数组的来源—>最后Protobuf编码回去

算法分析(部分算法)

1
2
3
4
5
6
// Base64编码表 - 标准表和变种表
const nU = {
4: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// reCAPTCHA自定义变种编码表
5: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.",
};
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
function ll(Z, m, r, t) {
// 只实现Base64编码部分,忽略其他分支
if ((Z >> 2 & 7) == 3) {
// 验证输入类型
if (typeof r !== "number") {
// 确保t有默认值
if (t === undefined) {
t = 0;
}

// 获取指定的编码表
const base64Chars = nU[t];
// reCAPTCHA实现中使用空字符串作为填充,而不是=
const padding = "";

// 计算结果数组大小
const resultLength = Math.floor(r.length / 3);
const result = new Array(resultLength);

let resultIndex = 0;

// 每次处理3个字节,生成4个Base64字符
for (let i = 0; i < r.length - 2; i += 3) {
// 获取3个连续字节
const byte1 = r[i];
const byte2 = r[i + 1];
const byte3 = r[i + 2];

// 计算4个Base64索引
const char1 = base64Chars[byte1 >> 2];
const char2 = base64Chars[((byte1 & 3) << 4) | (byte2 >> 4)];
const char3 = base64Chars[((byte2 & 15) << 2) | (byte3 >> m)];
const char4 = base64Chars[byte3 & 63];

// 拼接4个字符
result[resultIndex++] = "" + char1 + char2 + char3 + char4;
}

// 处理末尾不足3字节的情况
const remaining = r.length % 3;
let lastChars = "";

if (remaining === 2) {
// 剩余2个字节
const byte1 = r[r.length - 2];
const byte2 = r[r.length - 1];

const char1 = base64Chars[byte1 >> 2];
const char2 = base64Chars[((byte1 & 3) << 4) | (byte2 >> 4)];
const char3 = base64Chars[(byte2 & 15) << 2] || padding;

// 注意:与标准Base64不同,reCAPTCHA实现不使用=填充
lastChars = "" + char1 + char2 + char3;
} else if (remaining === 1) {
// 剩余1个字节
const byte1 = r[r.length - 1];

const char1 = base64Chars[byte1 >> 2];
const char2 = base64Chars[(byte1 & 3) << 4];

// 注意:与标准Base64不同,reCAPTCHA实现不使用=填充
lastChars = "" + char1 + char2;
}

// 如果有剩余字节,添加到结果中
if (lastChars) {
result[resultIndex] = lastChars;
}

// 连接所有结果
return result.join("");
}
}

// 其他操作码分支省略
return "";
}