classdef HybridCyberAttack
properties
dos_params struct
deception_params struct
attack_log struct
internal_state struct
end
methods
function obj = HybridCyberAttack(varargin)
p = inputParser;
addParameter(p, 's_m', 0.8, @isnumeric);
addParameter(p, 'l_M', 3.5, @isnumeric);
addParameter(p, 'theta1', 0.16, @isnumeric);
addParameter(p, 'theta2', 0.5, @isnumeric);
addParameter(p, 'gamma_bar', 0.1, @isnumeric);
addParameter(p, 'Phi', [1, 0; 0, 0.8], @ismatrix);
parse(p, varargin{:});
obj.dos_params = struct();
obj.dos_params.attack_type = 'aperiodic';
obj.dos_params.s_m = p.Results.s_m;
obj.dos_params.l_M = p.Results.l_M;
obj.dos_params.theta1 = p.Results.theta1;
obj.dos_params.theta2 = p.Results.theta2;
obj.deception_params = struct();
obj.deception_params.gamma_bar = p.Results.gamma_bar;
obj.deception_params.Phi = p.Results.Phi;
obj.attack_log = struct();
obj.attack_log.dos_events = [];
obj.attack_log.deception_events = [];
obj.attack_log.time = [];
obj.attack_log.deception_energy = []; % 新增:记录每次欺骗攻击的能量
obj.internal_state = struct();
obj.internal_state.last_switch_time = 0;
obj.internal_state.current_dos_state = 0;
obj.internal_state.attack_count = 0;
end
function [D_dos, dos_info] = generateDoSAttack(obj, t)
last_switch_time = obj.internal_state.last_switch_time;
current_state = obj.internal_state.current_dos_state;
attack_count = obj.internal_state.attack_count;
if current_state == 0
sleep_time = obj.dos_params.s_m + obj.dos_params.s_m * rand();
if t - last_switch_time >= sleep_time
current_state = 1;
last_switch_time = t;
attack_count = attack_count + 1;
obj.attack_log.dos_events = [obj.attack_log.dos_events; t, 1];
end
else
active_time = obj.dos_params.l_M * rand();
if t - last_switch_time >= active_time
current_state = 0;
last_switch_time = t;
obj.attack_log.dos_events = [obj.attack_log.dos_events; t, 0];
end
end
obj.internal_state.last_switch_time = last_switch_time;
obj.internal_state.current_dos_state = current_state;
obj.internal_state.attack_count = attack_count;
D_dos = current_state;
dos_info = struct('state', current_state, 'count', attack_count);
end
function [gamma_val, f_attack] = generateDeceptionAttack(obj, x, t)
if rand() <= obj.deception_params.gamma_bar
gamma_val = 1;
f_attack = [-tanh(x(1)); -tanh(0.8 * x(2))];
current_energy = norm(f_attack, 2);
max_energy = norm(obj.deception_params.Phi * x, 2);
if current_energy > max_energy
f_attack = f_attack * (max_energy / current_energy);
end
obj.attack_log.deception_events = [obj.attack_log.deception_events; t, 1];
obj.attack_log.deception_energy = [obj.attack_log.deception_energy; current_energy];
else
gamma_val = 0;
f_attack = zeros(size(x));
obj.attack_log.deception_events = [obj.attack_log.deception_events; t, 0];
obj.attack_log.deception_energy = [obj.attack_log.deception_energy; 0];
end
end
function [x_tilde, attack_info] = applyHybridAttack(obj, x_true, t)
[D_dos, dos_info] = obj.generateDoSAttack(t);
[gamma_val, f_attack] = obj.generateDeceptionAttack(x_true, t);
if D_dos == 1
x_tilde = NaN(size(x_true));
else
if gamma_val == 1
x_tilde = f_attack;
else
x_tilde = x_true;
end
end
obj.attack_log.time = [obj.attack_log.time; t];
attack_info = struct();
attack_info.dos_status = D_dos;
attack_info.gamma_status = gamma_val;
attack_info.f_attack = f_attack;
attack_info.time = t;
attack_info.original_signal = x_true;
attack_info.attacked_signal = x_tilde;
end
function is_valid = checkAttackFrequency(obj, t)
dos_events = obj.attack_log.dos_events;
if ~isempty(dos_events)
switch_count = sum(dos_events(:,1) <= t);
else
switch_count = 0;
end
max_allowed = obj.dos_params.theta1 + t / obj.dos_params.theta2;
is_valid = switch_count <= max_allowed;
if ~is_valid
warning('DoS攻击频率超过允许范围: %d > %.2f', switch_count, max_allowed);
end
end
function reset(obj)
obj.attack_log.dos_events = [];
obj.attack_log.deception_events = [];
obj.attack_log.time = [];
obj.attack_log.deception_energy = [];
obj.internal_state.last_switch_time = 0;
obj.internal_state.current_dos_state = 0;
obj.internal_state.attack_count = 0;
end
function closeOpenAttacks(obj, t_end)
if obj.internal_state.current_dos_state == 1
obj.attack_log.dos_events = [obj.attack_log.dos_events; t_end, 0];
obj.internal_state.current_dos_state = 0;
end
end
function stats = getAttackStatistics(obj)
stats = struct();
dos_events = obj.attack_log.dos_events;
if ~isempty(dos_events)
start_times = dos_events(dos_events(:,2)==1, 1);
end_times = dos_events(dos_events(:,2)==0, 1);
if length(start_times) > length(end_times)
start_times = start_times(1:end-1);
elseif length(end_times) > length(start_times)
end_times = end_times(2:end);
end
stats.dos_attack_count = length(start_times);
stats.dos_total_duration = sum(end_times - start_times);
else
stats.dos_attack_count = 0;
stats.dos_total_duration = 0;
end
if ~isempty(obj.attack_log.deception_events)
stats.deception_attack_count = sum(obj.attack_log.deception_events(:,2)==1);
stats.deception_ratio = stats.deception_attack_count / length(obj.attack_log.deception_events);
if stats.deception_attack_count > 0
stats.avg_deception_energy = mean(obj.attack_log.deception_energy(obj.attack_log.deception_events(:,2)==1));
else
stats.avg_deception_energy = 0;
end
else
stats.deception_attack_count = 0;
stats.deception_ratio = 0;
stats.avg_deception_energy = 0;
end
if ~isempty(obj.attack_log.time)
stats.total_simulation_time = max(obj.attack_log.time) - min(obj.attack_log.time);
else
stats.total_simulation_time = 0;
end
end
function attack_strength = computeAttackStrength(obj)
stats = obj.getAttackStatistics();
if stats.total_simulation_time > 0
dos_strength = stats.dos_total_duration / stats.total_simulation_time;
else
dos_strength = 0;
end
attack_strength = struct(...
'dos_strength', dos_strength, ...
'avg_deception_energy', stats.avg_deception_energy);
end
end
endclassdef AdaptiveFuzzyEventTrigger1gai
properties
% 事件触发参数
h % 采样间隔h=0.01
Omega % 模糊加权矩阵 Ω_j^χ(基于模糊状态的模糊ET加权矩阵)
psi_min % 最小阈值 ψ(给定为0.1)
psi_max % 最大阈值 ψ̄(给定为0.3)
varpi % 误差灵敏度参数 ϖ(给定为5)
M % 基础阈值标量 M%%%%%%%%%%%%%%%%%%%???(哪里给出)
% 事件触发状态
last_trigger_time % 上次触发时间
trigger_count % 触发次数统计
trigger_events % 触发事件记录(包含相关信息)
current_psi % 当前阈值函数值
release_instants % 释放时刻记录(记录事件释放(即触发)的具体时刻)
% 关联对象
observer % 关联的观测器对象,提供状态估计
fuzzy_system % 关联的模糊系统对象,提供系统动态和隶属度计算
cyber_attack % 关联的攻击对象,提供攻击状态信息
% 优化参数
optimization_config % 结构体,优化算法配置
search_results % 存储优化结果
% 攻击时间表
attack_schedule % 攻击时间表 Υ_{1,n}, Υ_{2,n},结构体,包含:Upsilon1:正常通信时段,Upsilon2:DoS 攻击时段
% 配置
verbose % 详细输出标志
end
methods
function obj = AdaptiveFuzzyEventTrigger1gai(varargin)
% 构造函数
p = inputParser;
addParameter(p, 'h', 0.01, @isnumeric);
addParameter(p, 'psi_min', 0.1, @isnumeric);
addParameter(p, 'psi_max', 0.3, @isnumeric);
addParameter(p, 'varpi', 5.0, @isnumeric);
addParameter(p, 'M', 0.5, @isnumeric);
addParameter(p, 'observer', [], @(x) isa(x, 'SwitchedFuzzyObserver') || isempty(x));
addParameter(p, 'fuzzy_system', [], @(x) isa(x, 'IntervalType2FuzzySystem') || isempty(x));
addParameter(p, 'cyber_attack', [], @(x) isa(x, 'HybridCyberAttack') || isempty(x));
addParameter(p, 'verbose', false, @islogical);
parse(p, varargin{:});
% 初始化参数
obj.h = p.Results.h;
obj.psi_min = p.Results.psi_min;
obj.psi_max = p.Results.psi_max;
obj.varpi = p.Results.varpi;
obj.M = p.Results.M;
obj.observer = p.Results.observer;
obj.fuzzy_system = p.Results.fuzzy_system;
obj.cyber_attack = p.Results.cyber_attack;
obj.verbose = p.Results.verbose;
% 初始化模糊加权矩阵
if ~isempty(obj.observer)
n = obj.observer.n;
obj.Omega = cell(obj.observer.r, 1);
for j = 1:obj.observer.r
obj.Omega{j} = eye(n);
end
else
obj.Omega = {eye(2)}; % 如果没有关联观测器,使用默认设置
end
% 初始化状态
obj.last_trigger_time = 0;
obj.trigger_count = 0;
obj.trigger_events = struct(...
'time', {}, ...
'state', {}, ...
'error', {}, ...
'chi', {}, ...
'left_term', {}, ...
'right_term', {}, ...
'psi_value', {}, ...
'is_trigger', {});
obj.release_instants = [];
obj.current_psi = p.Results.psi_max; % 当前自适应阈值函数ψ的值
% 初始化攻击时间表
obj.attack_schedule = struct('Upsilon1', [], 'Upsilon2', []);
% 优化配置
obj.optimization_config = struct(...
'max_iterations', 100, ...
'tolerance', 1e-4, ...
'learning_rate', 0.01, ...
'search_step', 0.1, ...
'search_upper_bound', 5.0, ...
'target_release', 50, ... % 目标释放次数 r̄_s
'max_k', 1000 ... % 最大迭代次数 k̄
);
obj.search_results = struct();
end
function obj = reset(obj)
% 重置事件触发器
obj.last_trigger_time = 0;
obj.trigger_count = 0;
obj.trigger_events = struct(...
'time', {}, ...
'state', {}, ...
'error', {}, ...
'chi', {}, ...
'left_term', {}, ...
'right_term', {}, ...
'psi_value', {}, ...
'is_trigger', {});
obj.release_instants = [];
obj.current_psi = obj.psi_max;
end
function obj = setAttackSchedule(obj, Upsilon1, Upsilon2)
% 设置攻击时间表 Υ_{1,n}, Υ_{2,n}
obj.attack_schedule.Upsilon1 = Upsilon1; % 正常通信时段
obj.attack_schedule.Upsilon2 = Upsilon2; % DoS攻击时段
end
function obj = setOmegaMatrix(obj, j, Omega_j)
% 设置第j条规则的模糊加权矩阵
if j <= length(obj.Omega)
obj.Omega{j} = Omega_j;%Omega_j:要设置的加权矩阵(n×n 矩阵)
else
error('规则索引超出范围');
end
end
function psi_value = computeAdaptivePsi(obj, e_error)
% 计算自适应阈值函数
error_norm_sq = norm(e_error, 2)^2;
exp_term = exp(-obj.varpi * error_norm_sq);
if error_norm_sq > obj.M / obj.varpi
numerator = obj.psi_min * (1 - exp_term) + 2 * obj.psi_max * exp_term;
denominator = 1 + exp_term;
psi_value = numerator / denominator;
else
psi_value = obj.psi_max;
end
% 确保在范围内%%%%%%%%%%%%%%%
psi_value = max(obj.psi_min, min(obj.psi_max, psi_value));
end
function [is_trigger, psi_value] = checkTriggerCondition(obj, t, x_sigma_current, e_error)
% 检查DoS攻击
[D_dos, ~] = obj.cyber_attack.generateDoSAttack(t);
if D_dos == 1
is_trigger = false;
psi_value = obj.psi_min;
% 记录事件
obj.recordEvent(t, x_sigma_current, e_error, [], [], [], psi_value, is_trigger);
return;
end
% 计算隶属度
chi = obj.computeMembershipDegrees(x_sigma_current);
% 计算加权矩阵
Omega_avg = zeros(size(obj.Omega{1}));
for j = 1:length(obj.Omega)
Omega_avg = Omega_avg + chi(j) * obj.Omega{j};
end
% 计算平方根
Omega_sqrt = sqrtm(Omega_avg);
% 计算左边项
left_term = norm(Omega_sqrt * e_error, 2)^2;
% 计算自适应阈值
if obj.varpi * norm(e_error, 2)^2 <= obj.M
psi_value = obj.psi_min;
else
psi_value = obj.computeAdaptivePsi(e_error);
end
obj.current_psi = psi_value;
% 计算右边项
right_term = psi_value * norm(Omega_sqrt * x_sigma_current, 2)^2;
% 检查触发条件
is_trigger = (left_term > right_term);
% 更新触发状态
if is_trigger
obj.trigger_count = obj.trigger_count + 1;
obj.last_trigger_time = t;
obj.release_instants = [obj.release_instants; t];
end
% 记录事件
obj.recordEvent(t, x_sigma_current, e_error, chi, left_term, right_term, psi_value, is_trigger);
end
function chi = computeMembershipDegrees(obj, x)
% 计算规则隶属度
if isempty(obj.fuzzy_system)
error('未关联模糊系统');
end
r = obj.fuzzy_system.r;
p = obj.fuzzy_system.p;
chi = zeros(r, 1);
% 计算前件变量值
rho = zeros(p, 1);
for j = 1:p
premise_func = obj.fuzzy_system.premise_vars{j};
rho(j) = premise_func(x);
end
% 计算每条规则的激活强度
for l = 1:r
activation = 1;% 初始化为1(乘法单位元)
for k = 1:p
% 获取隶属函数
lower_mem = obj.fuzzy_system.lower_MF{l, k}(rho(k));
upper_mem = obj.fuzzy_system.upper_MF{l, k}(rho(k));
activation = min(activation, min(lower_mem, upper_mem));
end
chi(l) = activation;
end
% 归一化
total_activation = sum(chi);
if total_activation > 0
chi = chi / total_activation;
else
chi = ones(r, 1) / r;
end
end
function recordEvent(obj, t, state, error, chi, left, right, psi, is_trigger)
% 创建事件数据结构
event_data = struct(...
'time', t, ...
'state', state, ...
'error', error, ...
'chi', chi, ...
'left_term', left, ...
'right_term', right, ...
'psi_value', psi, ...
'is_trigger', is_trigger);
% 添加到事件记录
if isempty(obj.trigger_events)
obj.trigger_events = event_data;
else
obj.trigger_events(end+1) = event_data;
end
% 显示日志
if obj.verbose
fprintf('时间 %.2f: 左项=%.4f, 右项=%.4f, 触发=%d\n', ...
t, left, right, is_trigger);
end
end
function [optimal_M, optimal_release] = optimizeMAlgorithm1(obj, x0, total_time)
% 实现算法1:M的优化算法
% 输入: x0 - 初始状态, total_time - 总仿真时间
% 输出: optimal_M - 最优M, optimal_release - 最优释放次数
%从优化配置中获取搜索参数
config = obj.optimization_config;
search_step = config.search_step;
search_upper = config.search_upper_bound;
target_release = config.target_release;%目标释放次数
% 搜索空间设置
m_values = 0:search_step:search_upper;%生成 M 值的搜索范围
release_counts = zeros(size(m_values));%存储每个 M 值对应的释放次数
best_M = obj.M;
best_release = inf;%将最佳释放次数初始化为无穷大
fprintf('开始优化M...\n');
fprintf('m0\t释放次数\t是否满足条件\n');%定义结果表格的列标题
fprintf('--------------------------------\n');
for idx = 1:length(m_values)
m0 = m_values(idx);
obj.M = m0;%获取当前 M 值并设置到对象中
% 运行仿真计算释放次数
release_count = obj.runSimulationForM(x0, total_time);
release_counts(idx) = release_count;
% 检查是否满足条件 r_s^{[m0]} < r̄_s
meets_condition = release_count < target_release;
%使用文本字符代替特殊符号
status = '是';
if ~meets_condition
status = '否';
end
fprintf('%.2f\t%d\t\t%s\n', m0, release_count, status);
% 更新最优值(满足目标条件且释放次数比当前最优值小)
if meets_condition && release_count < best_release
best_M = m0;
best_release = release_count;
end
end
% 保存搜索结果
obj.search_results.m_values = m_values;
obj.search_results.release_counts = release_counts;
obj.search_results.optimal_M = best_M;
obj.search_results.optimal_release = best_release;
% 更新当前M值
obj.M = best_M;
fprintf('--------------------------------\n');
fprintf('优化完成: 最优 M = %.3f, 释放次数 = %d\n', best_M, best_release);
optimal_M = best_M;
optimal_release = best_release;
end
function release_count = runSimulationForM(obj, x0, total_time)
% 为给定M值运行仿真并计算释放次数
config = obj.optimization_config;%获取存储在对象属性 optimization_config中的优化配置
% 重置系统(当观测器存在时执行)
if ~isempty(obj.observer)
obj.observer = obj.observer.resetObserver(x0);%重置关联的观测器对象
end
obj.reset();%重置事件触发器自身状态
% 初始化状态
x_true = x0;
x_sigma_prev = x0;
release_count = 0;
% 时间步长
time_steps = 0:obj.h:total_time;%obj.h代表采样周期,即事件触发器的采样时间
%处理每个时间步长的事件,包括攻击检测、状态获取和误差计算
for k = 1:min(length(time_steps), config.max_k)
t = time_steps(k);%获取当前仿真时间
% 生成随机欺骗攻击
gamma_val = 0;%设置默认值为0(无攻击)
if rand() < obj.cyber_attack.deception_params.gamma_bar
gamma_val = 1;
end%以概率 gamma_bar触发欺骗攻击
% 获取当前观测器状态(直接访问观测器的状态估计属性)
x_sigma_current = obj.observer.x_sigma;
% 计算误差
e_error = x_sigma_prev - x_sigma_current;%上次触发时的状态估计与当前估计的差异
% 获取DoS攻击状态
[D_dos, ~] = obj.cyber_attack.generateDoSAttack(t);
% 事件触发逻辑
if D_dos == 0 % 正常通信
% 计算隶属度
chi = obj.computeMembershipDegrees(x_sigma_current);
% 计算加权矩阵
Omega_avg = zeros(size(obj.Omega{1}));
for j = 1:length(obj.Omega)
Omega_avg = Omega_avg + chi(j) * obj.Omega{j};
end
% 检查触发条件
Omega_sqrt = sqrtm(Omega_avg);%计算加权矩阵的平方根
left_term = norm(Omega_sqrt * e_error, 2)^2;
% 根据算法1更新psi
psi_value = obj.computeAdaptivePsi(e_error);
right_term = psi_value * norm(Omega_sqrt * x_sigma_prev, 2)^2;
if left_term > right_term
% 触发事件
release_count = release_count + 1;
x_sigma_prev = x_sigma_current;
obj.release_instants = [obj.release_instants; t];
end
else % DoS攻击期间
psi_value = obj.psi_min;% 保持psi为最小值
end
obj.current_psi = psi_value;
% 模拟观测器状态变化(随机扰动)
obj.observer.x_sigma = obj.observer.x_sigma + randn(size(obj.observer.x_sigma)) * 0.01;%向当前状态添加随机扰动(xσ(t k)=xσ(t k−1)+Δx)
if ~isempty(obj.observer.fuzzy_system.C)
obj.observer.y_sigma = obj.observer.fuzzy_system.C * obj.observer.x_sigma;
end%更新输出估计(yσ=C*xσ)
end
% 记录最终释放次数
obj.trigger_count = release_count;
end
function plotOptimizationResults(obj)
% 绘制优化结果
if isempty(obj.search_results)
warning('没有优化结果数据');
return;
end
results = obj.search_results;
figure;
subplot(2, 1, 1);
plot(results.m_values, results.release_counts, 'b-o', 'LineWidth', 1.5);
hold on;
plot(results.optimal_M, results.optimal_release, 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r');
xlabel('M值');
ylabel('释放次数 r_s');
title('M优化结果');
grid on;
legend('释放次数', '最优值', 'Location', 'best');
subplot(2, 1, 2);
target_line = ones(size(results.m_values)) * obj.optimization_config.target_release;
plot(results.m_values, results.release_counts, 'b-o', results.m_values, target_line, 'r--', 'LineWidth', 1.5);
xlabel('M值');
ylabel('释放次数 r_s');
title('与目标释放次数比较');
legend('实际释放次数', '目标释放次数', 'Location', 'best');
grid on;
end
function stats = getOptimizationStatistics(obj)
% 获取优化统计信息
if isempty(obj.search_results)
stats = struct();
return;
end
results = obj.search_results;
stats = struct(...
'optimal_M', results.optimal_M, ...
'optimal_release', results.optimal_release, ...
'target_release', obj.optimization_config.target_release, ...
'search_range', [min(results.m_values), max(results.m_values)], ...
'min_release', min(results.release_counts), ...
'max_release', max(results.release_counts) ...
);
end
function plotTriggerHistory(obj)
% 绘制触发历史
if isempty(obj.trigger_events)
warning('没有触发事件记录');
return;
end
% 提取数据
times = [obj.trigger_events.time];
left_terms = [obj.trigger_events.left_term];
right_terms = [obj.trigger_events.right_term];
psi_values = [obj.trigger_events.psi_value];
is_trigger = [obj.trigger_events.is_trigger];
% 创建图形
figure('Name', '事件触发历史', 'Position', [100, 100, 1000, 800]);
subplot(3, 1, 1);
plot(times, left_terms, 'b-', times, right_terms, 'r--', 'LineWidth', 1.5);
title('触发条件比较');
xlabel('时间 (s)');
ylabel('值');
legend('左项', '右项', 'Location', 'best');
grid on;
subplot(3, 1, 2);
plot(times, psi_values, 'g-', 'LineWidth', 1.5);
title('自适应阈值变化');
xlabel('时间 (s)');
ylabel('ψ值');
grid on;
subplot(3, 1, 3);
stem(times, is_trigger, 'filled', 'MarkerSize', 4);
title('触发事件');
xlabel('时间 (s)');
ylabel('触发 (1=是)');
ylim([-0.1, 1.1]);
grid on;
sgtitle('事件触发历史分析');
end
end
end如何根据混合网络攻击模型获得事件触发机制所需要的攻击事件表