当前位置: 首页 > article >正文

STM32无RNG单元时,巧用ADC噪声与SysTick生成高随机性数值

1. 当你的STM32没有“骰子”时怎么办玩过单片机开发的朋友都知道随机数在很多场景里都扮演着关键角色。比如你想做一个抽奖小游戏或者让设备每次启动时生成一个唯一的ID又或者在一些简单的加密场景里需要一个不可预测的密钥。这时候一个靠谱的随机数来源就至关重要了。对于高端的STM32芯片比如F4、F7、H7系列它们内部集成了一个叫做**硬件随机数发生器RNG**的单元。这玩意儿就像芯片内置的一个“真·骰子”利用模拟电路的固有噪声来产生真正的随机数用起来特别省心直接调用HAL库的HAL_RNG_GetRandomNumber()函数就能拿到一个高质量的随机数。但问题来了我们手头大量使用的、性价比极高的中低端STM32比如经典的F1系列、G0系列它们为了控制成本和功耗往往没有这个“豪华配置”。没有硬件RNG难道就没办法了吗当然不是。这就好比你想做饭没有电饭煲难道就不吃米饭了用锅在炉子上也能煮出来。在嵌入式世界里我们有的是办法“创造”随机性。最常被提起的就是标准C库里的srand()和rand()这对组合拳。但我要先给你泼盆冷水只用它们得到的几乎是“假随机”。因为rand()本质上是一个确定的数学公式只要给srand()的“种子”一样它后面吐出来的数列就一模一样完全可预测。这用在游戏里可能每次重启游戏敌人的行动路线都相同那就太没意思了。所以核心矛盾就变成了如何为一个伪随机数发生器找到一个真随机的种子以及有没有办法直接获取真随机数这篇文章我就结合自己踩过的坑和实战经验给你分享两个在无RNG的STM32上特别实用的“土办法”一个是巧用系统滴答定时器SysTick来“制造”随机种子另一个是挖掘ADC模数转换器的噪声来“提取”真随机数。更妙的是我们还能把这两者结合起来形成一个既保证随机性、又兼顾效率的混合方案。无论你是做物联网设备、智能硬件还是简单的电子玩具这套思路都能让你摆脱随机数匮乏的困境。2. 剖析两种核心的随机数生成原理在动手写代码之前我们得先搞清楚我们要用的这两个“原料”到底是怎么回事。知其然更要知其所以然这样你才能在不同的项目里灵活变通而不是死记硬背代码。2.1 SysTick一个永不停止的“微妙计时器”SysTick是Cortex-M内核自带的一个24位递减计数器。它通常被配置为每1毫秒或一个你设定的固定时间间隔产生一次中断为操作系统提供心跳。但除了这个中断功能我们随时可以读取它的当前计数值SysTick-VAL。它为什么能作为随机种子呢想象一下你让用户去按一个按键从程序开始运行到用户按下按键中间经过的时间是毫秒甚至微秒级的。这个时间长度完全取决于用户的手速、反应对于单片机程序来说是不可预测的。SysTick-VAL这个值就在以系统时钟频率高速递减比如72MHz下每13.9纳秒减1你在“随机”的时刻去读取它得到的值在很大概率上也是随机的。但是这里有个大坑我踩过如果你的程序启动流程是固定的比如没有等待用户输入那么每次上电复位后程序运行到读取SysTick的那行代码所花费的机器周期数可能相差无几。这会导致你每次得到的“种子”都非常接近甚至在某些简单循环中可能会周期性地出现相同值随机性大打折扣。所以更靠谱的做法是结合一个非确定性的用户事件。比如在程序启动后先在一个循环里等待用户按下某个按键或者等待一个外部传感器的不稳定信号。在检测到事件的那个“瞬间”立刻读取SysTick-VAL。这个“瞬间”的计时器值就具备了很好的随机性。这相当于把人的行为或物理世界的噪声引入了随机种子的生成过程。2.2 ADC噪声芯片内部的“微观风暴”如果说SysTick是借用了时间的不可预测性那么ADC噪声就是直接挖掘芯片模拟世界的本质随机性。STM32的ADC分辨率至少是12位这意味着它能把一个0到3.3V的电压分成4096个等级2^124096来测量。关键点来了ADC的最后几位通常是LSB最低有效位是非常不稳定的。即使你给ADC引脚接一个理论上非常稳定的电压比如通过两个精密电阻对电源进行分压得到一个精确的1.65V你连续读取ADC转换结果也会发现数值会在一个很小的范围内跳动比如在2048附近上下波动几个数字。这个跳动主要来源于芯片内部的热噪声和量化噪声。热噪声是电子器件中电子的热运动产生的而量化噪声是ADC转换过程本身固有的。这两种噪声在物理层面上都是真随机的。这就给我们提供了一个绝佳的真随机数来源我们可以故意去读取这个噪声。方法就是设置一个ADC通道接一个稳定的电压源比如分压电路然后高速、连续地采样ADC。每次采样我们只取转换结果的最低1位或2位因为高位是稳定的电压值只有低位在随机波动。然后我们把多次采样得到的这些低位“碎片”拼接起来就能组成一个多位数的、高质量的真正随机数。我实测过用这个方法产生的随机数序列通过专业的随机性测试如NIST测试套件的表现确实可以接近硬件RNG的水平。但它的代价也很明显速度慢耗时间。ADC一次转换需要几个到几十个微秒要采集足够多的位来组成一个32位的随机数可能需要上百次转换耗时数毫秒。在实时性要求高的场合这可能是无法接受的。3. 实战构建一个混合随机数生成器理解了原理我们就可以动手搭建一个实用的方案了。单独使用SysTick种子或ADC噪声都有其局限性最好的办法是“强强联合”。3.1 第一步用ADC噪声生成高质量的“种子池”我们首先利用ADC噪声来创建一个一次性的、高质量的随机种子。这个种子不需要在每次需要随机数时都生成可以在系统初始化时生成一次用于播种伪随机数发生器或者作为后续混合生成的基石。这里有一个提升效率的技巧使用DMA直接存储器访问来批量采集ADC数据。这样CPU就可以解放出来去做其他事情等DMA搬运完一批数据比如256个后再来处理它们。// 假设使用STM32CubeMX/HAL库以下为示例代码框架 #define ADC_SAMPLE_COUNT 256 uint32_t adc_buffer[ADC_SAMPLE_COUNT]; void ADC_RNG_Init(void) { // 1. 初始化ADC设置一个通道例如接在稳定的分压电压上 // 2. 启用DMA配置为循环模式将数据搬运到 adc_buffer // 3. 启动ADC } uint32_t GetTrueRandomSeed(void) { uint32_t seed 0; uint8_t bit_position 0; // 等待DMA采集到足够的数据可以通过DMA中断或查询标志位 while(/* DMA传输未完成 */) { // 可以加入超时机制 } // 处理采集到的数据取每个样本的低2位拼接到seed中 for(int i 0; i ADC_SAMPLE_COUNT bit_position 32; i) { // 取ADC值的低2位 (adc_buffer[i] 0x03) uint8_t noise_bits adc_buffer[i] 0x03; // 将这两个位放入seed的当前空闲位置 seed | (noise_bits bit_position); bit_position 2; // 每次增加2位 // 如果ADC噪声只取最低1位则用 (adc_buffer[i] 0x01)且 bit_position 1 } // 如果采集了256个样本每个取2位我们就能得到512位的原始数据 // 但seed只有32位这里我们实际上是用前16个样本16*232位就填满了seed。 // 更多的样本可以用来做后处理比如异或混合增强随机性。 // 一个简单的增强将整个buffer的数据进行异或混合 for(int i 0; i ADC_SAMPLE_COUNT; i) { seed ^ adc_buffer[i]; } return seed; }这个GetTrueRandomSeed()函数虽然耗时可能需要几毫秒但它只在系统启动时调用一次生成一个“种子池”或初始种子这个代价是完全可以接受的。3.2 第二步用SysTick的动态值作为快速补充生成了高质量的初始种子后我们的伪随机数发生器rand()就有了一个很好的起点。但是如果我们需要连续、快速地生成大量随机数rand()的序列仍然是确定性的。为了在每次调用时都增加不可预测性我们可以引入SysTick的当前值进行“扰动”。思路是将SysTick的瞬态值与伪随机数发生器的输出进行混合。这里不直接用SysTick作为种子因为我们已经用更好的ADC种子初始化了而是把它作为一个动态的“搅拌器”。// 使用ADC种子初始化标准库随机数发生器 srand(GetTrueRandomSeed()); // 定义一个增强型的随机数获取函数 uint32_t GetEnhancedRandom(void) { uint32_t sysTickVal SysTick-VAL; // 获取当前SysTick值 uint32_t pseudoRand rand(); // 获取伪随机数 // 将两者进行异或混合。异或操作能很好地保留随机性。 // 也可以尝试更复杂的混合比如乘以一个奇数后相加。 uint32_t finalRandom pseudoRand ^ sysTickVal; return finalRandom; }这样做的好处是基础随机性好rand()序列的起点种子是真随机的。动态扰动强每次调用GetEnhancedRandom都会混入一个高速变化的SysTick值即使攻击者知道了rand()的内部状态也很难预测下一次输出因为SysTick值取决于函数被调用的精确时刻。速度快一次rand()调用加上一次内存读取和一次异或运算开销极小适合在循环或中断中频繁调用。3.3 第三步设计一个完整的、可配置的随机数模块在实际项目中我们最好把它封装成一个模块根据不同的应用场景对随机性要求高 vs 对速度要求高来灵活配置。// random_utils.h #ifndef __RANDOM_UTILS_H #define __RANDOM_UTILS_H #include stdint.h #include stdbool.h typedef enum { RNG_MODE_FAST, // 快速模式仅使用播种后的rand()SysTick扰动 RNG_MODE_STANDARD, // 标准模式如上文所述的混合模式 RNG_MODE_TRUE // 真随机模式每次调用都使用ADC噪声非常慢 } RNG_Mode_t; void RNG_Init(void); bool RNG_SeedWithADC(uint32_t sampleCount); // 用ADC噪声重新播种 uint32_t RNG_Get(RNG_Mode_t mode); #endif// random_utils.c #include random_utils.h #include main.h // 包含你的ADC、SysTick相关头文件 static bool isSeeded false; static uint32_t adc_seed 0; void RNG_Init(void) { // 默认使用ADC种子初始化一次 if(RNG_SeedWithADC(128)) { // 采样128次 isSeeded true; srand(adc_seed); } else { // 如果ADC种子失败降级使用SysTick随机性较差但好过固定值 srand(SysTick-VAL); isSeeded true; // 标记已播种但记录质量 } } bool RNG_SeedWithADC(uint32_t sampleCount) { // 实现ADC采样并生成种子的逻辑更新 adc_seed // 返回成功或失败 // ... (具体实现参考上文GetTrueRandomSeed思路) adc_seed generatedSeed; return true; } uint32_t RNG_Get(RNG_Mode_t mode) { if(!isSeeded) { RNG_Init(); // 懒初始化 } switch(mode) { case RNG_MODE_FAST: // 最简单快速适合对随机性要求不高的游戏、简单调度 return rand(); case RNG_MODE_STANDARD: // 推荐的混合模式兼顾性能与质量 return rand() ^ SysTick-VAL; case RNG_MODE_TRUE: // 用于密钥生成等安全场景每次调用都慢 // 可以设计为采集少量ADC样本与当前rand()和SysTick混合 uint32_t fastPart rand() ^ SysTick-VAL; uint32_t truePart 0; // 快速采集几个ADC样本例如4次取低位 for(int i0; i4; i) { truePart (truePart 2) | (ReadSingleADC() 0x03); } return fastPart ^ truePart; default: return rand(); } }这样在你的主程序中需要快速随机数时调用RNG_Get(RNG_MODE_FAST)需要高随机性时调用RNG_Get(RNG_MODE_STANDARD)在极少数需要最高安全性的环节如生成初始密钥使用RNG_Get(RNG_MODE_TRUE)或直接调用RNG_SeedWithADC。4. 不同应用场景下的选择与优化建议方案有了但具体怎么用还得看你的项目需求。我根据常见的几种嵌入式场景给你一些具体的建议。4.1 场景一设备唯一ID或启动标识生成很多物联网设备需要在第一次启动时生成一个全球唯一的标识符UUID的一部分或者一个随机的设备编号。这种场景对随机性的质量要求最高因为它直接关系到设备的身份唯一性。我的建议是必须使用ADC噪声作为核心熵源。在设备出厂首次启动的初始化流程中调用RNG_SeedWithADC函数并使用较大的采样次数比如512次甚至1024次确保采集到足够的熵。生成足够长的随机数。一个32位的随机数仍然有重复的概率。你可以用这个高质量的种子初始化srand()然后连续调用rand()获取多个32位数拼接成一个128位或更长的标识符。考虑结合芯片唯一ID。STM32都有一个96位的唯一设备标识符Unique Device ID。你可以将ADC生成的随机数与这个唯一ID进行哈希运算比如简单的SHA-256如果资源允许这样生成的标识符既包含了物理不可克隆的随机性又绑定了芯片本身几乎不可能重复。4.2 场景二简单游戏或动态效果如LED随机闪烁做一个呼吸灯流水灯太普通了想让你做的智能台灯或者玩具的灯光效果每次都不一样、更灵动这种场景对随机数的生成速度要求高但对随机性的质量要求相对较低。攻击者不会去预测你的下一个LED是哪一颗亮起。我的建议是在程序开始时用一次ADC种子或SysTick种子初始化srand()即可。甚至可以直接用HAL_GetTick()基于SysTick的毫秒计数器的返回值作为种子虽然随机性一般但足够简单。在需要随机数的循环中直接调用rand()。速度极快效果也完全能满足视觉上的“随机”感。如果想效果更好一点可以采用RNG_MODE_FAST模式。如果连初始化时的一次ADC采样都觉得耗时可以退而求其次在循环中结合SysTick-VAL的低位进行微调也能打破rand()序列的周期性。4.3 场景三简单的通信协议或数据混淆有些轻量级的通信协议为了降低连续数据被误判为命令的风险或者只是想给数据包做个简单的混淆需要用到随机数。这种场景需要一定的随机性来避免模式可被轻易识别但又不能引入太大的延迟。我的建议是采用标准的混合模式RNG_MODE_STANDARD。这是性价比最高的选择。它用ADC种子打下了良好的基础确保了不同设备、不同启动周期下序列的起始差异很大。同时每次调用混入SysTick值使得同一序列内部的关联性被大大削弱外部观察者很难找出规律。可以定期例如每小时或每天用ADC重新播种一次。这能进一步降低长期运行后随机数序列可能被分析破解的风险。你可以在SysTick中断里设置一个软件计数器时间到了就置位一个标志在主循环中检查这个标志并执行RNG_SeedWithADC(64)使用较小的采样次数以降低对主循环的阻塞。4.4 性能与随机性的权衡表格为了更直观我把几种方法的权衡点总结成下面这个表格你可以在选型时快速参考方法随机性质量生成速度CPU占用适用场景关键注意事项纯rand()极低极快极低对随机性无要求的模拟、演示必须提供变化的种子否则序列固定SysTick作种子低快低简单的游戏、非关键动态效果依赖不可预测的用户/外部事件来读取种子ADC噪声作种子高慢仅初始化一次初始化时高所有需要较好随机性的场景的基础需稳定电压源采样次数影响质量混合模式 (ADC种子SysTick扰动)中高快低通用推荐通信、中等安全需求标识、复杂效果在速度和质量间取得最佳平衡纯ADC噪声连续生成极高极慢持续高密钥生成、安全启动、唯一ID严重牺牲实时性通常只用于初始化5. 避坑指南与进阶思考最后分享几个我在实际项目中踩过的坑和一点进阶想法希望能帮你少走弯路。第一个坑ADC参考电压的稳定性。我们依赖ADC噪声的前提是输入的电压本身是稳定的。如果你直接用电源电压VCC作为ADC的参考电压同时又用电阻对VCC分压作为输入那么当电源波动时ADC读数的整个值都会漂移噪声就被淹没了。尽量使用STM32内部稳定的参考电压如VREFINT通道作为基准或者确保你的分压源是独立于VCC的精密基准源。第二个坑SysTick的周期性。在极其规律的任务中比如每1毫秒执行一次的定时任务中读取SysTick可能会读到规律的值。避免在周期性的中断服务程序ISR中直接读取SysTick作为唯一随机源。如果非要用可以结合中断发生时的某个外部IO状态即使未连接读取的电平也有噪声或者多个定时器的计数值进行异或。第三个坑伪随机数发生器的算法。标准库的rand()函数通常实现为线性同余发生器LCG其随机性质量一般且周期有限。对于要求更高的应用可以考虑实现一个更复杂的算法比如梅森旋转算法Mersenne Twister虽然它占用的内存稍多但周期极长随机性分布更好。你可以用ADC噪声初始化它的状态向量。进阶思考熵池Entropy Pool的概念。在专业的密码学随机数生成器中会维护一个“熵池”不断收集各种不可预测的事件按键时间、网络数据包间隔、ADC噪声等作为熵源然后通过一个密码学安全的哈希函数如SHA-256从熵池中提取随机数。我们在STM32上也可以模仿这种思想开辟一小块内存作为熵池在系统空闲时用ADC慢速采集噪声存入池中在外部中断发生时将事件发生时的精确时间多个定时器计数值混入池中。当需要高质量随机数时对整个熵池做哈希运算输出。这能极大地提升随机数的安全上限适合对安全有严苛要求的边缘设备。说到底在资源受限的单片机上做随机数就是在物理世界的不可预测性和有限的计算资源与时间之间做精巧的平衡。希望我今天分享的这套结合ADC与SysTick的混合方案能成为你工具箱里一件趁手的武器。下次当你的项目需要一点“不确定性”的魔法时不妨试试看。

相关文章:

STM32无RNG单元时,巧用ADC噪声与SysTick生成高随机性数值

1. 当你的STM32没有“骰子”时,怎么办? 玩过单片机开发的朋友都知道,随机数在很多场景里都扮演着关键角色。比如,你想做一个抽奖小游戏,或者让设备每次启动时生成一个唯一的ID,又或者在一些简单的加密场景里…...

MicroPython ESP32 UART Modbus 故障诊断与主从切换

1. 从“偷听”开始:理解UART监听Modbus的核心价值 大家好,我是老张,在工业自动化和物联网这块摸爬滚打了十几年。今天想和大家聊聊一个非常实用,但又常常被新手朋友觉得有点“玄乎”的场景:用一块小小的ESP32开发板&am…...

NOAA 中国区域 18 类地面气象要素逐日数据(1942-2025 年 8 月)汇总与 CSV 格式解析

一、引言 NOAA(美国国家海洋和大气管理局)的全球地面气象逐日数据集(GHCN-Daily/GSOD)是气象科研、气候分析、工程规划等领域的核心基础数据,涵盖全球超 10 万个气象站点的多维度观测记录。本文聚焦中国区域&#xff…...

eNSP实战:从零到一构建高可用无线校园网仿真方案

1. 为什么你需要用eNSP搞定一个高可用的无线校园网? 如果你是一名网络工程专业的学生,或者刚入行的网络工程师,面对“校园网”这个课题,是不是感觉头大?设备贵、环境复杂、不敢乱动真机……这些我都经历过。十年前我刚…...

Python之a2anet包语法、参数和实际应用案例

a2anet包概述 a2anet是一个用于实现Attention Aggregation Network (A2-Net) 架构的Python库,主要用于点云数据的深度学习处理。A2-Net是一种高效的点云特征提取网络,通过自注意力机制捕捉点之间的长距离关系,在点云分类、分割等任务中表现出…...

Python之a2a-agent-mcpserver-generator包语法、参数和实际应用案例

a2a-agent-mcpserver-generator 包功能概述 a2a-agent-mcpserver-generator 是一个专为Python设计的高级工具包,主要用于快速构建和部署多客户端服务器架构。它基于异步编程模型,支持多线程和协程,特别适合开发需要处理大量并发连接的网络应用…...

第8讲 数据库的设计与实施

一、数据库设计的特点1.数据库设计方法新奥尔良方法基于E-R模型的数据库设计方法基于3NF的设计方法对象定义语言(Object Definition Language,ODL)方法2.数据库设计的基本步骤1)需求分析获取需求是整个设计过程的基础。进行数据库设计时首先必须准确了解与分析用户的…...

Springboot+vue宠物领养救助平台的设计与实现

文章目录前言源码获取(稀缺资源,尽快转存到自己网盘,防止失效)详细视频演示具体实现截图后端框架SpringBoot前端框架Vue持久层框架MyBaits成功系统案例:参考代码数据库前言 博主介绍:CSDN特邀作者、985高校计算机专业…...

Springboot+vue房屋租赁管理系统的设计与实现

文章目录前言源码获取详细视频演示具体实现截图后端框架SpringBoot前端框架Vue持久层框架MyBaits成功系统案例:数据库前言 博主介绍:CSDN特邀作者、985高校计算机专业毕业、现任某互联网大厂高级全栈开发工程师、Gitee/掘金/华为云/阿里云/GitHub等平台持续输出高质…...

Windows下5分钟搞定内网穿透:qydev和飞鸽对比实测(附避坑指南)

Windows内网穿透实战:从零到精通的避坑与效率指南 最近在帮几个刚入行的朋友搭建本地开发环境的外部访问时,发现大家普遍对“内网穿透”这个概念既熟悉又陌生。熟悉的是,几乎每个开发者都遇到过需要临时把本地的Web服务、数据库或者测试API暴…...

全面指南:探索域名解析的五大实用方法

1. DNS查询:互联网的“电话本”是如何工作的? 每次你在浏览器里输入“www.baidu.com”并按下回车,到页面加载出来,这背后其实发生了一系列精密的“寻址”操作。这个把好记的域名翻译成计算机能识别的IP地址(比如“14.2…...

避坑指南:Simulink Scope导出数据总出错?这5个参数设置90%的人没搞对

避坑指南:Simulink Scope导出数据总出错?这5个参数设置90%的人没搞对 如果你经常和Simulink打交道,尤其是需要把Scope里那些漂亮的波形数据导出来,在MATLAB里做进一步分析、画报告图,或者存档,那你大概率踩…...

别让这些软件,偷走你新学期的效率!电脑卡顿元凶排查指南。

“开学才三天,电脑打开Word都要转圈圈!”“PPT做到一半直接卡死,差点想砸电脑!”这几天小A收到不少类似的私信:明明上学期还好好的,怎么新学期一开电脑就卡成PPT?(图片由AI生成&…...

开学焕新,一步到位!这台「全能学霸本」,让你从宿舍赢到图书馆

回想一下当年选电脑的自己,是不是满脑子的“性能拉满,游戏全开”,非高性能游戏本不选?结果呢,明明也不怎么玩游戏,愣是每天背着不够轻便的笔记本爬四五层楼,去教室、去图书馆、去自习室。还没毕…...

保姆级教程:在Ubuntu 22.04上为ROS2 Humble切换Cyclone DDS(含网卡指定技巧)

保姆级实战:在Ubuntu 22.04上为ROS2 Humble深度优化Cyclone DDS配置 最近在实验室调试一个多机器人协同项目,节点间通信时不时出现延迟抖动,排查了半天才发现,默认的通信中间件在复杂的网络拓扑下有点“力不从心”。和几位深耕机器…...

MobileNetV2实战:如何在树莓派上部署轻量级图像分类模型(附PyTorch代码)

从理论到实战:在树莓派上部署并极致优化MobileNetV2图像分类模型 当你在树莓派上尝试运行一个标准的ResNet-50模型时,可能会发现它慢得令人沮丧——推理一张224x224的图像可能需要数秒,这完全无法满足实时应用的需求。这正是轻量级神经网络架…...

华为防火墙+CentOS搭建GRE隧道实战:从端口映射到策略路由全解析

华为防火墙与CentOS GRE隧道实战:打通混合云网络的关键一步 最近在帮一家客户做混合云架构迁移,他们有个挺典型的需求:本地数据中心跑着核心业务,但部分服务想平滑迁移到公有云上,同时还得保证两边的应用能像在一个局域…...

SAP SQ01 用户权限查询 - AGR_USER 表关系解析与应用

1. 从SQ01查询说起:为什么AGR_USER表是权限管理的“核心枢纽” 如果你在SAP系统里做过权限相关的查询或者审计,大概率用过SQ01这个事务码。SQ01是SAP标准的查询工具,功能强大,但说实话,我第一次用它来查用户权限的时候…...

物流优化中的智能算法选择指南:何时用NS?LNS还是ALNS?

物流优化中的智能算法选择指南:何时用NS?LNS还是ALNS? 在物流与供应链管理的核心地带,无论是仓库里拣货员的行走路径,还是公路上运输车辆的调度排班,背后都隐藏着一个个复杂的组合优化难题。对于负责技术选…...

实战指南:Burp Suite 在安卓高版本模拟器中的HTTPS抓包与证书信任配置

1. 为什么安卓高版本抓包这么麻烦?从“信任”说起 大家好,我是老张,一个在安全测试这行摸爬滚打了十来年的老兵。今天咱们不聊虚的,就聊一个让很多刚入行的朋友头疼不已的问题:用Burp Suite抓安卓APP的HTTPS包&#xf…...

循环神经网络(RNN)在时序数据处理中的核心优势与应用场景解析

1. 为什么说RNN是处理“带记忆”数据的首选? 如果你用过传统的神经网络,比如前馈神经网络或者CNN来处理图片,你会发现它们有个特点:每次输入都是独立的。比如你给一张猫的图片,它输出“猫”;给一张狗的图片…...

CentOS8网络服务重启失败?试试这个NetworkManager的隐藏技巧

CentOS 8网络服务重启失败?试试这个NetworkManager的隐藏技巧 最近在CentOS 8上折腾服务器,不少朋友都遇到了一个看似简单却让人头疼的问题:想用经典的systemctl restart network命令重启网络服务,结果系统直接给你泼一盆冷水&…...

RFSOC XCZU47DR开发套件在5G射频基带与相控阵系统中的应用实践

1. 从“概念”到“信号”:为什么我们需要RFSOC XCZU47DR? 如果你正在捣鼓5G、相控阵雷达或者任何需要处理大量无线信号的玩意儿,那你肯定对“原型验证”这个词又爱又恨。爱的是,它意味着你的天才想法有机会变成现实;恨…...

告别Magnet!Hammerspoon窗口管理全攻略:从基础分屏到高级布局

告别Magnet!Hammerspoon窗口管理全攻略:从基础分屏到高级布局 如果你是一名Mac用户,并且每天需要与十几个窗口打交道——浏览器、代码编辑器、终端、文档、通讯软件——那么你一定对窗口管理这件事又爱又恨。爱的是macOS流畅的动画和精致的界…...

华为手机NFC车钥匙全攻略:从开通到使用,手把手教你告别实体钥匙

华为手机NFC车钥匙:从入门到精通,彻底解放你的口袋 不知道你有没有过这样的经历:急匆匆出门,走到车边一摸口袋,心里咯噔一下——车钥匙又忘带了。或者,在超市采购完,双手拎满购物袋,…...

高光谱数据处理实战:从.mat到真彩色图像的完整流程(含常见问题解答)

高光谱数据处理实战:从.mat到真彩色图像的完整流程(含常见问题解答) 你是否也曾面对一堆共享的.mat格式高光谱数据,感觉无从下手?明明知道里面藏着丰富的光谱信息,却卡在第一步——如何把它变成一张人眼能直…...

HCIP数通 vs 安全 vs 云计算:2024年华为认证方向选择指南(含薪资对比)

HCIP数通 vs 安全 vs 云计算:2024年华为认证方向选择指南(含薪资对比) 站在2024年的十字路口,如果你是一名网络工程师或者正在IT领域寻求突破的从业者,面对华为HCIP认证下琳琅满目的方向,感到一丝迷茫&…...

WinServer 2012 R2实战:如何通过组策略彻底禁用域用户离线登录(附注册表清理技巧)

WinServer 2012 R2企业级安全加固:从组策略到注册表,全面封堵域用户离线登录风险 在金融、医疗、研发等对数据安全有着严苛要求的行业里,IT管理员们常常面临一个看似微小却影响深远的挑战:当员工带着笔记本电脑离开公司网络&#…...

海康威视内部Ubuntu镜像源配置全攻略(含18.04/20.04/22.04版本)

海康威视内部Ubuntu镜像源配置全攻略(含18.04/20.04/22.04版本) 如果你正在参与海康威视相关的项目开发,无论是内部研发还是外部协作,搭建一个高效的开发环境是第一步。而环境搭建中,最基础也最影响效率的一环&#xf…...

如何用Cofounder快速创建RESTful API与AsyncAPI文档:完整指南

如何用Cofounder快速创建RESTful API与AsyncAPI文档:完整指南 【免费下载链接】cofounder ai-generated apps , full stack generative UI 项目地址: https://gitcode.com/gh_mirrors/co/cofounder Cofounder是一款强大的AI驱动的全栈应用生成工具&#xff…...