获取随机数并且每次和上一次的不相同

本文介绍了一种使用JavaScript实现的随机数生成方法,确保每次生成的随机数不会重复。通过自定义数组删除方法和利用jQuery选择器实现按钮点击事件,演示了如何从指定数组中移除已选取的元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

获取到随机数,并且每次获取的随机数和上一次获取的不相同

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button class="btn">点击</button>
</body>
<script src="jquery-1.11.3.js"></script>
<script>
    //自定义删除数组元素
    Array.prototype.del = function (n) {
        if (n < 0) return this;
        return this.slice(0, n).concat(this.slice(n + 1, this.length));
    }
    var arr = [1, 2, 3, 4, 5];
    var arr2 = [];
    $('.btn').click(function () {
        if (arr2.length > 0) {
            var index = Math.floor((Math.random() * arr2.length));
            var temp = arr2[index];
        } else {
            var index = Math.floor((Math.random() * arr.length));
            var temp = arr[index];
        }
        var num = arr.indexOf(temp);//获取到取到值的索引
        arr2 = arr.del(num);//删除后成为新的数组
        console.log(temp);
    });
</script>
</html>
<think>好的,我现在需要帮助用户解决在STM32F103单片机上电时生成随机数并在指定范围内的问题。首先,我得回顾一下用户的问题,确保我理解正确。用户希望每次上电时生成同的随机数并且这些数要在指定的范围内。同时,用户提到可能使用内置的RNG或者软件算法来实现。过,STM32F103系列是否有硬件RNG呢? 我记得STM32F1系列F4系列的区别,F4比如F407确实有硬件RNG模块,但F103可能没有。用户提到的引用中,引用[2][3]提到了STM32F4的RNG,而用户现在用的是F103,所以可能没有内置的硬件RNG。这点需要确认。查阅资料,STM32F103的数据手册,确认其外设列表,确实没有RNG模块。所以用户只能用软件算法来生成随机数。 接下来,用户的需求是上电时生成同的随机数。软件算法通常依赖种子,如果每次上电的种子相同,生成的随机数序列也会相同。因此,如何获得同的种子是关键。可能的解决方案是使用一个随机的种子源,比如未使用的ADC引脚读取的噪声值,或者RTC的时钟值,或者其他固定的硬件源。 比如,用户可以使用ADC读取一个悬空的引脚,由于引脚上的噪声,每次上电时读取的值会有微小差异,这样可以作为种子。或者,如果系统有RTC,并且电池供电,可以利用RTC的计时值作为种子。如果没有RTC,可能需要其他方法。 然后,生成指定范围的随机数。通常可以用取模运算,但需要注意模运算可能引入的偏差。更好的方法是使用范围缩放,或者拒绝采样法,确保均匀分布。 接下来,我需要整理实现步骤: 1. 获取随机种子:使用ADC读取悬空引脚的值,或者结合多个固定的源(如未初始化的内存、定时器值等)来生成种子。 2. 初始化伪随机数生成器:比如C标准库的srand()rand(),使用获取的种子初始化。 3. 生成指定范围的随机数:通过缩放或取模,并处理可能的偏差。 需要注意,软件生成的随机数适合加密用途,但如果是普通应用,比如简单的随机延迟或选择,应该足够。 然后,用户提到的引用中,引用[1]提到了加密算法随机性测试,但用户可能需要这么高的安全性,所以软件算法应该可以。过要提醒用户注意应用场景,如果涉及安全,需更严格的方法。 可能的代码实现:配置ADC读取一个悬空引脚,将读取的值作为种子,然后调用srand(),之后用rand()生成随机数,再映射到指定范围。例如,生成1-100的随机数,可以用rand() % 100 + 1,但需要注意模运算的偏差,可以通过循环丢弃超出均匀范围的值,或者使用其他方法。 另外,用户可能没有外接硬件RNG,所以必须依赖软件。需要检查STM32F103的ADC配置方法,如何初始化读取。同时,悬空引脚可能会有噪声,但需要测试是否足够随机。 总结步骤: - 初始化ADC,读取悬空引脚的值作为种子。 - 使用srand(seed)初始化随机数生成器。 - 使用rand()生成随机数,并通过计算映射到目标范围。 可能需要测试同种子生成的效果,确保每次上电种子同。此外,如果ADC读取的值变化大,可能需要结合其他源,比如定时器的计数值或者系统时钟的抖动。 最后,提醒用户如果要求更高的随机性,可以考虑外部硬件模块,或者更复杂的算法。</think>### 实现STM32F103生成指定范围随机数的方法 #### 1. **硬件随机数生成(STM32F103无内置RNG)** STM32F103系列**无硬件随机数生成器(RNG)**,需依赖软件算法实现随机数生成[^2][^3]。 #### 2. **生成随机种子的方法** - **ADC噪声采样** 读取未连接的ADC引脚(如悬空引脚)的噪声值作为种子。 ```c uint32_t get_seed(void) { ADC1->CR2 |= ADC_CR2_ADON; // 启动ADC ADC1->CR2 |= ADC_CR2_ADON; // 二次启动开始转换 while (!(ADC1->SR & ADC_SR_EOC)); // 等待转换完成 return ADC1->DR; // 返回ADC值作为种子 } ``` 需配置ADC为单次采样模式,选择未使用的通道。 - **结合系统时钟定时器** 利用上电时系统时钟的抖动或未初始化内存的值生成种子: ```c uint32_t volatile uninitialized_var; uint32_t seed = HAL_GetTick() ^ (uint32_t)&uninitialized_var; ``` #### 3. **软件随机数生成算法** - **线性同余生成器(LCG)** 简单高效的伪随机数算法,公式为: $$ X_{n+1} = (aX_n + c) \mod m $$ 示例实现: ```c static uint32_t lcg_seed; void srand_lcg(uint32_t seed) { lcg_seed = seed; } uint32_t rand_lcg(void) { lcg_seed = (1103515245 * lcg_seed + 12345) % 0x7FFFFFFF; return lcg_seed; } ``` #### 4. **映射到指定范围** 若需生成范围$[min, max]$的随机数,避免取模偏差: ```c uint32_t rand_range(uint32_t min, uint32_t max) { uint32_t range = max - min + 1; uint32_t rand_val = rand_lcg(); // 或使用rand() return min + (rand_val % range); } ``` #### 5. **完整实现流程** ```c // 步骤1: 初始化ADC获取种子 uint32_t seed = get_seed(); srand_lcg(seed); // 或srand(seed)使用标准库 // 步骤2: 生成指定范围随机数(例如1~100) uint32_t random_num = rand_range(1, 100); ``` #### 注意事项 - **随机性质量**:软件算法生成的随机数可用于加密场景,仅适用于一般用途[^1]。 - **优化种子**:可混合多个熵源(如ADC值 + 定时器值 + 内存未初始化区域)提升种子随机性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值