string_analyze/rules/core/coding.rs
1// string_analyze/src/rules/core/coding.rs
2use crate::rules::lazy_rule;
3use crate::tool::{is_base64, is_hex};
4
5lazy_rule!(
6 RE_BASE64 = r#"\b[A-Za-z0-9+/\-_]{8,}={0,2}"#, // 筛选器
7 "发现 Base64 编码数据", // 描述
8 40, // 重要性
9 3.0, // 最低混合熵要求
10 |s, _| is_base64(s) // 验证闭包
11);
12lazy_rule!(
13 RE_HEX = r#"(?i)(?:(?:0x|\\x|%)?[0-9a-f]{2}[\s,;:\-|]*){2,}(?:0x|\\x|%)?[0-9a-f]{2}"#,
14 "发现 十六进制 (Hex) 编码数据",
15 45,
16 2.0,
17 |s, _| is_hex(s)
18);
19lazy_rule!(
20 RE_BRAINFUCK = r#"(?:[<>+\-.\[\],]{20,})"#,
21 "发现疑似 Brainfuck 代码",
22 40,
23 |slice, _input| {
24 let op_types = ['>', '<', '+', '-', '.', ',', '[', ']']
25 .iter()
26 .filter(|&&op| slice.contains(op))
27 .count();
28 op_types >= 2
29 }
30);
31lazy_rule!(
32 RE_JSFUCK = r#"(?:[\[\]()!+]\s*){20,}"#,
33 "发现疑似 JSFuck 代码",
34 40,
35 |s, _| s.contains('!') || s.contains('(') || s.contains(')')
36);
37lazy_rule!(
38 RE_MORSE = r#"(?:[.-]{1,6}(?:[ \t]+|[ \t]*/[ \t]*)){4,}[.-]{1,6}"#,
39 "发现 摩斯电码",
40 40
41);
42lazy_rule!(
43 RE_BACON_HINT = r#"(?i)\b(?:aabbb|ababa|baaba|babba|abbba){5,}\b"#,
44 "发现 疑似培根密码特征",
45 40
46);
47lazy_rule!(
48 RE_FOYAN = r#"(?:佛曰|如是我闻|舍利弗|须菩提|婆伽婆|摩诃萨|世尊|比丘|阿耨多罗|三藐三菩提)?[::]?\s*[\u{4e00}-\u{9fa5}]{15,}"#,
49 "发现 佛曰编码",
50 40,
51 |slice, _| {
52 let trimmed = slice.trim_start();
53 if trimmed.starts_with("佛曰")
54 || trimmed.starts_with("如来")
55 || trimmed.starts_with("如是我闻")
56 {
57 return true;
58 }
59
60 // 核心特征字
61 let high_weight_dict = [
62 '皤', '埵', '阇', '墀', '迦', '楞', '咩', '钵', '醯', '羯', '唎', '娑', '谛', '穆',
63 '怛', '陀', '哆',
64 ];
65
66 // 次核心特征字
67 let low_weight_dict = [
68 '佛', '菩', '提', '萨', '摩', '诃', '般', '若', '波', '罗', '蜜', '阿', '弥', '舍',
69 '利', '南', '无',
70 ];
71
72 let mut score = 0;
73
74 let check_len = slice.chars().count().min(50);
75
76 for c in slice.chars().take(check_len) {
77 if high_weight_dict.contains(&c) {
78 score += 2;
79 } else if low_weight_dict.contains(&c) {
80 score += 1;
81 }
82 }
83
84 score >= 10
85 }
86);
87// [entropy ] [3.156] ~呜嗷~~嗷嗷呜~嗷呜喵呜喵呜喵~嗷~~呜~喵喵呜嗷喵嗷呜嗷呜嗷~喵~呜呜呜喵嗷呜喵喵喵呜喵喵
88// [delta_entropy ] [3.798] ~呜嗷~~嗷嗷呜~嗷呜喵呜喵呜喵~嗷~~呜~喵喵呜嗷喵嗷呜嗷呜嗷~喵~呜呜呜喵嗷呜喵喵喵呜喵喵
89// [gram_entropy2 ] [3.798] ~呜嗷~~嗷嗷呜~嗷呜喵呜喵呜喵~嗷~~呜~喵喵呜嗷喵嗷呜嗷呜嗷~喵~呜呜呜喵嗷呜喵喵喵呜喵喵
90// [composite_entropy] [4.075] ~呜嗷~~嗷嗷呜~嗷呜喵呜喵呜喵~嗷~~呜~喵喵呜嗷喵嗷呜嗷呜嗷~喵~呜呜呜喵嗷呜喵喵喵呜喵喵
91// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
92// [entropy ] [2.962] ~呜嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷
93// [delta_entropy ] [3.540] ~呜嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷
94// [gram_entropy2 ] [3.540] ~呜嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷
95// [composite_entropy] [3.796] ~呜嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷呜嗷嗷嗷嗷嗷呜呜呜呜嗷呜嗷呜呜喵呜喵嗷喵嗷喵呜~呜~嗷~嗷~呜嗷
96// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
98// [entropy ] [1.573] ~~~~~~~~~~~!!!!!!!!!!!!!!###############
99// [delta_entropy ] [0.343] ~~~~~~~~~~~!!!!!!!!!!!!!!###############
100// [gram_entropy2 ] [1.833] ~~~~~~~~~~~!!!!!!!!!!!!!!###############
101// [composite_entropy] [0.789] ~~~~~~~~~~~!!!!!!!!!!!!!!###############
102lazy_rule!(
103 RE_SHOUYIN = r#"[咯嘤呜呀哈嘿嗷喵啊~~]{15,}"#,
104 "发现 兽音编码",
105 40,
106 3.5 // 最小混合熵要求
107);
108
109lazy_rule!(
110 RE_OOK = r#"(?i)(?:Ook[.\!?]\s*){8,}"#,
111 "发现 Ook! 混淆代码",
112 45
113);
114lazy_rule!(
115 RE_BRACKETS = r#"(?:[\[\](){}<>]\s*){20,}"#,
116 "发现 括号混淆 特征",
117 35
118);
119lazy_rule!(
120 RE_ZERO_WIDTH = r#"[\u{200b}-\u{200f}\u{2060}\u{2061}\u{2062}\u{2063}\u{2064}\u{feff}]{10,}"#,
121 "发现 零宽字符隐写",
122 35
123);