You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Arduino(SAMD21)中使用strcpy等函数复制unsigned char失败求助

解决Adafruit Feather M0(SAMD21)上AES加密结果无法保存的问题

我之前在SAMD21平台上也碰到过类似的问题,结合你的描述,大概率是两个常见坑导致的:局部变量生命周期失效或者用字符串函数处理二进制加密数据,下面给你具体的解决思路和代码示例:

问题根源分析

  1. 局部数组的生命周期问题:如果你的encrypt()函数里是在栈上创建局部char数组存储加密结果,函数执行完毕后栈内存会被系统回收覆盖,这时候你再去复制这个数组,拿到的已经是无效的垃圾数据了。
  2. 字符串函数不适合处理二进制数据:AES加密输出的是二进制字节流,其中很可能包含\0(字符串结束符),strcpy/strncpy这类函数会在遇到\0时停止复制,导致你只能拿到部分加密结果。

具体解决步骤

1. 让加密函数直接写入外部数组(最优方案)

不要在encrypt()内部创建局部数组存储结果,而是把要保存结果的数组作为参数传入函数,让加密逻辑直接写入这个外部数组——这样数组的生命周期由调用方控制,不会出现函数返回后数据失效的问题。

示例代码:

// AES加密函数:直接将结果写入传入的output数组
void aes_encrypt(uint8_t* plaintext, uint8_t* output, size_t data_len, const uint8_t* key) {
    // 这里替换成你的AES-128/256加密逻辑
    // 比如使用Crypto库的话:
    AES aes;
    aes.setKey(key, 16); // 16是AES-128的key长度,256的话传32
    aes.encryptBlock(output, plaintext);
}

void loop() {
    // 定义生命周期覆盖整个loop的加密结果数组
    uint8_t encrypted_result[16]; // AES块大小固定为16字节,不管128还是256
    uint8_t plaintext[16] = "TestData12345678";
    uint8_t aes_key[16] = "MySecretKey12345"; // AES-128的key

    // 直接加密到外部数组
    aes_encrypt(plaintext, encrypted_result, sizeof(plaintext), aes_key);

    // 现在encrypted_result里就是有效的加密结果,可以正常存储或使用
    // 比如打印验证:
    for(int i=0; i<16; i++){
        Serial.print(encrypted_result[i], HEX);
        Serial.print(" ");
    }
    Serial.println();
}

2. 用memcpy代替字符串复制函数

如果因为某些原因必须在encrypt()内部使用局部数组,一定要:

  • 把局部数组声明为static,让它存储在全局内存(而非栈),函数返回后不会被释放;
  • 用memcpy复制所有字节,不要用字符串函数。

示例代码:

void aes_encrypt(uint8_t* plaintext, uint8_t* output, size_t data_len, const uint8_t* key) {
    static uint8_t temp_encrypted[16]; // 静态数组,生命周期永久
    AES aes;
    aes.setKey(key, 16);
    aes.encryptBlock(temp_encrypted, plaintext);

    // 用memcpy复制所有字节,不受\0影响
    memcpy(output, temp_encrypted, data_len);
}

3. 注意数组大小匹配

确保存储加密结果的目标数组大小足够:

  • AES-128/256的块大小都是16字节,如果是ECB模式,加密后的数据长度和明文的块对齐长度一致;
  • 如果用CBC/GCM等模式,还要预留IV(初始化向量)和校验值的空间,比如CBC模式需要额外16字节存储IV。

额外提醒(针对SAMD21)

Feather M0的栈空间有限(默认一般是2KB左右),如果在函数里创建大的局部数组很容易导致栈溢出,破坏其他变量的数据。所以尽量避免在函数内定义大数组,优先用全局数组或者传入外部数组的方式。

内容的提问来源于stack exchange,提问作者user5156141

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:18:24