资讯动态

多跳WSNs物理层安全路径选择:硬件噪声建模与Matlab仿真

发布时间:2026/10/17 5:26:17 来源:尧图企业网站定制
做无线传感器网络仿真的朋友大概率都碰过这种场景节点沿着部署区域一跳一跳地把数据汇聚到基站也就是多跳收集-传输WSNs。本来只要考虑能量和时延就够了可一旦引入窃听者和硬件噪声网络性能立刻被打回原形。今天想聊的就是这套场景下用路径选择方法做性能增强的完整思路以及我实测可跑的Matlab代码实现。这个问题的核心在于多跳收集让数据链路变长每个中继节点既是转发者也是不可或缺的环节而窃听者只需监听其中任何一跳就可能破坏整条路径的安全性再加上实际射频器件不可避免地存在相位噪声、非线性失真等硬件噪声信噪比并不会随着发射功率无限提升。路径选择方法要解决的就是在已知信道统计信息和窃听者大致位置的条件下避开被监听的脆弱链路同时容忍硬件损伤选出端到端安全性能最强的多跳路径。这篇文章适合正在做无线安全、WSNs路由算法仿真的研究生和工程师也适合想把安全容量理论落到Matlab仿真的入门读者。我会从模型建立、路径选择算法、代码实现到调试心得完整讲清楚。1. 为什么多跳收集-传输需要性能增强1.1 多跳结构带来的安全隐患无线传感器网络最常见的业务形态就是“收集-传输”周围部署大量廉价节点数据沿着多跳中继汇聚到唯一或者少数几个汇聚节点。多跳的好处是每跳发射功率可以压得很低适合电池供电的小节点也能绕开障碍物。但代价也很明显数据要经过的中间节点越多暴露给窃听者的机会就越多。传统安全方案大多依赖加密算法可传感器节点的算力和存储都有限不可能跑重量级密码协议就算跑得动密钥分发也是头疼事。物理层安全因此被拿上台面——它利用信道本身的随机性让窃听者即使截获信号也无法有效解码。这时路径选择就变成了一个“零成本”的网络层防御手段。我们不需要修改物理帧结构不需要增加额外硬件只要在路由计算时避开那些容易泄密的链路就能明显提升网络的抗窃听能力。多跳网络天然就是个有向图每条候选链路的“安全质量”可以计算成权重路径选择就转成图上的优化问题。这个思路在单跳点对点系统里是没有的单跳只有一个信道只能通过加扰、功率分配来硬碰硬而多跳给了我们“绕路”的机会这正是WSNs结构本身带来的额外自由度。1.2 硬件噪声让理想假设崩塌很多入门文献在推导安全容量时都默认收发机是理想硬件信噪比可以无限增大。可实际节点用的都是集成射频前端振荡器有相位噪声混频器有IQ不平衡功率放大器有非线性失真这些非理想因素最终表现为一种“硬件损伤”。结果就是无论你把发射功率调到多高接收端的等效信噪比都会到一个天花板很难超过某个值。这个天花板对合法链路和窃听链路是同时存在的但对合法链路的影响往往更致命因为合法接收端的信噪比基础更高更容易被天花板卡住。举个简单例子假设硬件损伤系数beta是0.1当发射功率极大时实际信噪比包含硬件噪声趋近于1/beta也就是10约等于10dB。这意味着就算信道条件再好合法接收端也拿不到超过10dB的等效信噪比。如果此时窃听信道也差不多安全容量的余量就被压缩得厉害。路径选择方法需要把这种“非理想硬件天花板”提前建模进去否则算出来的安全路径在真实平台上根本不可用——你以为是选了一条更安全的路径结果因为链路本身的实际安全容量早被硬件噪声限制住收益和仿真对不上。所以我一直强调性能增强不能只盯着“窃听者距离有多近”硬件噪声是另一个同样需要公式化的约束条件。忽略它仿真结果就是空中楼阁。2. 系统模型与关键参数如何定2.1 网络拓扑与信道模型我先说说标准的仿真场景模型。假设一片100m乘100m的区域里随机撒了N个传感器节点其中一个固定为源节点S一个固定为汇聚节点D附近有一个窃听者E。所有传感器节点都有接收、转发能力但发射功率相同且工作在半双工模式。任意两个节点之间是否可以直接通信由通信半径R决定距离超过R就别想了信道太弱连接不存在。信道系数我习惯写成h sqrt(G / (1 d^alpha)) * rayleigh_channel;其中d是两点距离alpha通常取3或4G是参考距离处的路径损耗常数rayleigh_channel是均值为0、方差为1的复高斯随机变量代表小尺度衰落。这个模型比较简单但足够说明问题。路径损耗指数alpha取值对结果影响很大alpha越大远端链路的代价越高多跳的优势越明显alpha小的时候一跳大功率传输可能反而更划算。做仿真时alpha建议固定为3不要一上来就同时改多个参数否则不好定位结果变化的原因。所有链路的噪声功率统一设为sigma2发射功率P固定。这样每条链路的接收信噪比就能算出来了。但注意这个接收信噪比不是经典意义上的“SNR”因为后面还要加硬件损伤项。2.2 窃听者模型与安全容量定义窃听者一般有两种建模方式一种是只知道窃听者位置范围用随机位置做最坏情况另一种是假设窃听者会尝试在每一跳上解码数据因此每条合法链路旁边都有一个对应的窃听信道系数h_e。实际仿真里我喜欢固定一个窃听者坐标但每次蒙特卡罗都重新生成它到所有节点的瑞利衰落系数这样既保留了随机性又避免位置分布过于发散导致结果方差太大。安全容量可以定义为合法信道容量减去窃听信道容量的正部但更严谨的做法是考虑硬件噪声后的形式SINR_legit (P * abs(h)^2) / (P * beta * abs(h)^2 sigma2); SINR_eve (P * abs(h_e)^2) / (P * beta * abs(h_e)^2 sigma2); C_s max(0, log2(1 SINR_legit) - log2(1 SINR_eve));这里beta是硬件损伤系数含义是发射机和接收机综合失真占总接收功率的比例。P * beta * abs(h)^2这一项就是“硬件噪声”和信号功率成正比所以当P增大到一定程度后SINR不再随P增长而是逼近1/beta。这个模型常被叫做“非理想硬件下的有效SNR上限”在物理层安全文献里已经是被广泛认可的简化方案。注意安全容量是比特每秒每赫兹bps/Hz为单位多跳时如果要加总必须想清楚端到端语义。我倾向于不用累加理由下一节会讲。2.3 硬件噪声建模的细节技巧很多人在Matlab里实现硬件噪声时直接把信道响应h的绝对值平方乘以beta再乘以P放到分母里。这个做法是对的但有个坑beta到底该取多少我建议先取0.01试一轮非常理想再看0.1这时你会发现安全容量普遍掉得很厉害。实际芯片的等效beta值通常介于0.01到0.1之间低端射频器件可能更高。仿真时最好把beta作为输入参数方便画不同硬件条件下的性能对比曲线。另一个细节是窃听者接收时同样存在硬件噪声。这个很多人会忽略直接把窃听信噪比按理想情况算导致安全容量虚高。窃听者的接收机也是真实器件不可能完全理想所以分母里也要有对应的beta_e * P * abs(h_e)^2项。我通常让beta_e和beta取相同值除非你专门研究“窃听者硬件更好/更差”的场景那也可以分开设置。3. 路径选择方法从“最短路径”到“最安全瓶颈路径”3.1 算法选型与目标函数设计多跳路径选择本质上是个图搜索问题。每个传感器节点是图顶点有通信链路的节点对之间连一条边边的权重就是这条链路的安全容量C_s。我们要在源节点S和汇聚节点D之间找一条路径让端到端安全性能最好。听起来像一个“最长路径”问题但千万别直接用最长路径算法因为端到端安全容量不是一条链路上的累加值。我的做法是采用最大最小max-min准则。定义一条路径P由若干条链路e组成这条路径的端到端安全容量定义为C_path min_{e in P} C_s(e)也就是“链路瓶颈值”。路径选择的优化目标就是在所有从S到D的路径中找到让C_path最大的那一条。为什么是瓶颈而不是累加因为在多跳解码转发场景下每一跳都是独立传输的数据要在每个中继节点被完整解码并重新加密或者利用物理层安全机制重新编码后再发出去。如果其中某一跳被窃听者破译了整条消息那么即便其余跳安全容量再高整条路径就等于泄露了。好比运输一批重要物资车队里最容易被劫的那段路决定了整趟运输的安全性而不是把每段路的“安全评分”加起来看平均。max-min准则还有一个工程优势它对链路安全容量的绝对标定不敏感只关心排序和瓶颈值。即使模型参数有偏差选出来的路径仍然大概率是稳健的。相比之下如果用“端到端安全速率等于各跳安全速率的和”这种定义在时延受限的收集网络中并不成立因为总时延会限制发送速率平均安全速率往往是由最低的那跳决定的。3.2 最大最小安全路径的求解图论里求最大瓶颈路径有现成套路把Dijkstra算法的松弛条件从“距离累加”改成“瓶颈取最小再取最大”。具体状态量是b[v]从源节点S到节点v的所有路径中能达到的最大瓶颈值。初始化b[S]无穷大其他b[v]-无穷大。每次从未确定节点里挑b最大的节点u然后松弛它的邻居vcandidate min(b[u], w(u,v)) if candidate b[v] b[v] candidate; prev[v] u; end这个写法很容易理解反正瓶颈路径只能由“之前路径瓶颈”和“当前链路安全容量”两者中较小的那个决定如果经过u能让v的瓶颈变大就更新v。用堆优化的话复杂度是O((|V||E|) log|V|)节点数几十到几百的仿真完全没压力。需要注意如果某条链路的安全容量是0这条边参与路径没有任何意义因为瓶颈会被直接拉成0。我在生成图的时候会直接删掉C_s低于某个阈值比如0.01的边。不然算法会选中一条看似有路径、实际端点安全容量约等于0的坏路径还占用计算量。3.3 为什么不是累加安全容量这块我原来也犯过迷糊。早期有一版代码我把安全容量累加作为路径权重然后跑最长路径结果选出来的路径经常绕过所有近距离中继故意走远路只为凑出更高的总容量。问题是当路径多跳时每条链路的C_s都只有一点点累加值虽然大但实际转发过程中如果某一跳被截获了前面累加的全白搭。打个比方一段视频分成好几个片段传只要中间某一片段被黑客拿走整个视频就泄密了不能说其他片段都传得很安全就算总“安全片段数”很高也没意义。而如果采用瓶颈值算法自然会在“跳数多、单跳安全容量被拉低”和“跳数少、链路距离太大导致单跳信噪比低”之间做一个折中。它天然就会寻找那种每跳信噪比都不错、且窃听者毛可能不太容易下手的路径。所以我在仿真结果里看到max-min选择的路径一般不是最短路径但也不会绕得太离谱它更像一条“均衡路径”。4. Matlab实现从参数初始化到结果复现4.1 环境搭建与参数设定Matlab里不需要额外工具箱基础函数就够了。推荐的脚本结构是一个主文件负责参数初始化、调用函数、跑蒙特卡罗、画图两个函数文件分别负责“链路安全容量计算”和“最大最小路径选择”。下面是我常用的参数块clear; clc; rng(2024); % 场景参数 N 20; % 节点总数 area 100; % 正方区域边长 R 40; % 最大通信距离 S 1; % 源节点编号 D N; % 汇聚节点编号 % 信道参数 alpha 3; % 路径损耗指数 G 1; % 参考路径损耗增益 sigma2 1e-6; % 接收机噪声功率 P 1; % 发射功率 beta 0.05; % 硬件损伤系数 % 蒙特卡罗次数 MC 1000;节点位置生成我习惯用二维均匀随机分布但为了保证S和D固定并位于区域两侧会在生成后手动修改坐标。例如让S在(5, 50)D在(95, 50)这样网络是沿水平方向收集数据的更符合“收集-传输”的语义。窃听者位置可以放在路径中部的某个扰动位置比如(50, 20)代表它埋伏在源到汇聚的主流区域附近。4.2 核心函数链路安全容量计算单条链路的函数需要注意输入输出清楚function [cs, sinr_legit, sinr_eve] calc_secrecy_capacity(P, h, h_e, beta, sigma2) % 合法链路 sinr_legit (P * abs(h)^2) / (P * beta * abs(h)^2 sigma2); % 窃听链路 sinr_eve (P * abs(h_e)^2) / (P * beta * abs(h_e)^2 sigma2); % 安全容量 cs max(0, log2(1 sinr_legit) - log2(1 sinr_eve)); end这个函数假设合法链路和窃听链路的发射功率都是P但事实上窃听链路中“发射机”是当前正在发送数据的合法节点所以功率相同没问题。实际使用中要小心abs(h)为极小值的情况可能导致SINR溢出为Inf安全容量变成Inf。因此我在调用前会做一次钳位如果abs(h)^2小于某个极小值就把它设为极小值。这是很多数值问题的来源也是后面要提到的排查点。4.3 核心函数最大最小路径选择下面这个函数输入邻接矩阵W其中W(i,j)是链路安全容量若不连通则填-Inf或0。注意矩阵对角线填0但调用时不会走对角线。function [path, bottleneck] max_min_path(W, S, D) n size(W,1); b -inf(1,n); % 最大瓶颈值 prev zeros(1,n); visited false(1,n); b(S) inf; for step 1:n % 找未访问节点中b最大的 [~, u] max(b .* (~visited)); % 简单版n不大时可用 if u D, break; end visited(u) true; for v 1:n if visited(v), continue; end w W(u,v); if w 0, continue; end cand min(b(u), w); if cand b(v) b(v) cand; prev(v) u; end end end % 回溯路径 path D; cur D; while cur ~ S prev(cur) ~ 0 cur prev(cur); path [cur, path]; end if path(1) ~ S path []; bottleneck 0; else bottleneck b(D); end end这里在找最大b的节点时用了带逻辑索引的乘法注意如果b为-Inf或者对应visited为1时会被筛掉。节点数量大时建议改成优先队列但本例20个节点完全够用。回溯的兜底逻辑一定要写否则图不连通时容易死循环。4.4 蒙特卡罗仿真与绘图主程序里对每个蒙特卡罗样本重新生成所有瑞利衰落系数然后构建邻接矩阵调用路径选择函数。与此同时我还会计算一条“最短路径”作为对比基准这里的“最短”不是跳数少而是按欧氏距离最短的Dijkstra路径对应传统路由只考虑能耗和时延时最可能被选中的路径。sec_opt zeros(MC,1); sec_shortest zeros(MC,1); for mc 1:MC pos rand(N,2) * area; pos(S,:) [5, 50]; pos(D,:) [95, 50]; posE [50, 20]; W_sec -inf(N,N); W_dist inf(N,N); for i 1:N for j 1:N if i j, continue; end d norm(pos(i,:) - pos(j,:)); if d R h sqrt(G/(1d^alpha)) * (randn(1,2) * [1;1j] / sqrt(2)); h_e sqrt(G/(1norm(pos(i,:)-posE)^alpha)) * (randn(1,2) * [1;1j] / sqrt(2)); cs calc_secrecy_capacity(P, h, h_e, beta, sigma2); if cs 0.01 W_sec(i,j) cs; else W_sec(i,j) -inf; end W_dist(i,j) d; end end end [path_opt, bt_opt] max_min_path(W_sec, S, D); if ~isempty(path_opt) sec_opt(mc) bt_opt; end % 最短路径忽略窃听与硬件噪声影响只按距离 [path_short, ~] max_min_path(-W_dist, S, D); % 妙用将距离矩阵取负求最小值 if ~isempty(path_short) sec_shortest(mc) min(W_sec(sub2ind(size(W_sec), path_short(1:end-1), path_short(2:end)))); end end % 画CDF figure; cdfplot(sec_opt); hold on; cdfplot(sec_shortest); legend(路径选择方法, 传统最短路径); xlabel(端到端安全容量 (bps/Hz)); ylabel(CDF);我刻意用了一次取负距离矩阵再跑max_min_path的小技巧这样就能在同一个函数里求出距离最小路径省事。注意代码里计算复高斯衰落时用(randn(1,2)*[1;1j]/sqrt(2))来生成标准复高斯变量这种写法的好处是避免循环里重复调用randn两次减少随机数序列漂移。仿真次数MC取1000时能得到比较稳定的CDF曲线。你会看到两条曲线明显分离路径选择方法的CDF更靠右意味着同样概率下能拿到的安全容量更高。有些样本里传统最短路径的安全容量是0直接画图会看到从0到某个值的跳跃这正好说明传统路由在很多场景下是完全不设防的。5. 常见问题与排查技巧实录5.1 安全容量出现负数或NaN这个我遇到太多次了。理想情况下安全容量取max(0, ...)但如果你偷懒没取max负数会出现会把max_min_path里的w判断搅乱。NaN更危险通常来自log2(1Inf)或者log2(1-1e-16)之类的浮点边界。解决方法是信道衰减项加上一个极小值如abs(h)^2 max(abs(h)^2, 1e-12)计算完安全容量后发一句判断语句把非有限值当成0处理。不要试图在路径选择阶段再“容错”喂给算法矩阵里的每个元素都必须是干净的实数。5.2 路径选择结果不合理如果你发现选出的路径绕了很多圈甚至出现回环多半是邻接矩阵里有非对称或者有未初始化元素。因为路径问题是建立在有向图上的而实际无线信道在一定近似下是互易的h_ij和h_ji统计相同但具体衰落样本不同。构建W矩阵时要明确方向从i发送到j合法信道用h_ij窃听信道用同一时刻的h_e_ij。我一般把W对角线和不可达边都设成-Inf这样路径不会经过。另外注意如果某条链路的C_s刚好等于0.01边界被删掉后可能让图断开这时要检查是否是因为阈值设得太高建议调成0.001再试。5.3 内存与复杂度问题N20时压根没有内存问题但一旦扩展到N100直接三层循环每条链路的蒙特卡罗会变得很慢。优化思路是预先算好距离矩阵把距离大于R的索引对直接跳过复用信道衰落矩阵而不是每次重新生成。另外max_min_path里的那个max(b .* (~visited))写法在N变大时是O(N^2)如果要跑大规模网络请换成优先队列或至少用排序。对学术仿真来说N30以内是足够的更多节点时要考虑集群或并行工具箱。下面是几个常见问题的速查表方便调试时直接对号入座表现可能原因处理办法安全容量全是0窃听者离所有节点太近或beta过大降低beta把窃听者拉远或用位置随机化多次取平均路径为空图不连通增大R或检查节点位置边界或删边阈值过高仿真曲线几乎重叠安全容量被硬件噪声压制路径选择没意义减小beta看是否恢复差异或加入能量约束让路径长度更敏感计算结果每次不同随机种子未固定在脚本开头设置rng代码速度极慢双层循环内部又生成随机数提前生成信道矩阵或向量化循环6. 一些扩展与实操体会这个仿真框架搭起来之后扩展方向其实很多。比如说你可以加一个协作干扰节点它专门发射噪声来恶化窃听信道。这种情况下路径选择就不只是选转发链路还要决定哪个节点当干扰机问题瞬间变成“联合路由与干扰调度”。也可以用功率分配的想法路径上每个节点的发射功率不一定平均分配可以在瓶颈链路附近提高功率其他链路适当降低整体安全容量还能再涨一截。我后来在这个模型里加了一行节点剩余能量权重让路径选择在安全容量和能耗之间做折中效果也很直接。最后说几点我自己的体会。第一路径选择方法作为性能增强手段核心优势在于实现成本和协议改动都很小它不是一个复杂的信号处理算法而是一个“聪明地选择信源和路由”的决策问题因此非常适合作为WSNs物理层安全仿真的入门课题。第二硬件噪声务必要建模别嫌它“不过是多一项分母”。很多安全论文的理想假设一放到工程板卡上就失效正是因为这个上限被忽略。第三仿真初始阶段一定要先画一条路径看链路级结果再跑蒙特卡罗否则出了错误很难定位是信道生成问题、容量计算问题还是路径搜索问题。路线千万条先单条后整网能省下大量查错时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑