如何在C语言中创建每个单元为512位的2×M二维数组?
解决方案
首先明确:512位等于64字节(8位=1字节),所以每个数组单元需要存储64字节的随机数据。你之前用unsigned char[2][M],每个元素仅1字节,完全无法满足需求。下面是具体实现方式:
1. 定义512位数据类型
先通过typedef封装一个64字节的数组类型,方便后续复用:
#define M 1024 // 定义512位数据类型(对应64字节) typedef unsigned char uint512[64];
2. 修改密钥结构体
将public_key和private_key改为2×M的uint512数组,这样每个单元天然对应512位存储空间:
typedef struct { uint512 public_key[2][M]; uint512 private_key[2][M]; } key_pair; // 注意这里要加分号,你原代码漏了这个语法细节
3. 实现加密安全的随机数生成
你的Python代码用了secrets模块(加密安全级别的随机数),C里别用srand()+rand()(伪随机,安全性极低,不适合密钥场景),建议用系统提供的加密随机源:
Linux/macOS 下的实现
直接读取/dev/urandom设备获取加密安全的随机字节:
#include <stdio.h> #include <stdlib.h> #define M 1024 typedef unsigned char uint512[64]; typedef struct { uint512 public_key[2][M]; uint512 private_key[2][M]; } key_pair; void keygen(key_pair *key) { // 打开加密随机源 FILE *urandom = fopen("/dev/urandom", "rb"); if (!urandom) { perror("Failed to open /dev/urandom"); exit(EXIT_FAILURE); } // 批量填充所有密钥单元 for (int i = 0; i < M; i++) { // 读取64字节填充private_key的两个维度单元 fread(key->private_key[0][i], 1, 64, urandom); fread(key->private_key[1][i], 1, 64, urandom); // 读取64字节填充public_key的两个维度单元 fread(key->public_key[0][i], 1, 64, urandom); fread(key->public_key[1][i], 1, 64, urandom); } fclose(urandom); } // 使用示例 int main() { key_pair my_keys; keygen(&my_keys); // 此处可使用生成的密钥 return 0; }
Windows 下的实现
调用Windows API的CryptGenRandom函数,编译时需要链接advapi32.lib:
#include <windows.h> #include <wincrypt.h> #include <stdio.h> #define M 1024 typedef unsigned char uint512[64]; typedef struct { uint512 public_key[2][M]; uint512 private_key[2][M]; } key_pair; void keygen(key_pair *key) { HCRYPTPROV hProv; // 获取加密服务提供者 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { printf("CryptAcquireContext failed: %d\n", GetLastError()); exit(EXIT_FAILURE); } // 批量生成随机密钥 for (int i = 0; i < M; i++) { CryptGenRandom(hProv, 64, key->private_key[0][i]); CryptGenRandom(hProv, 64, key->private_key[1][i]); CryptGenRandom(hProv, 64, key->public_key[0][i]); CryptGenRandom(hProv, 64, key->public_key[1][i]); } CryptReleaseContext(hProv, 0); } // 使用示例 int main() { key_pair my_keys; keygen(&my_keys); return 0; }
额外注意点
- 你原代码的几个语法错误:结构体定义末尾缺分号、函数参数类型错误(应该是
key_pair *key而非key *key_pair)、srand(time(NULL))末尾缺分号。 - 为什么不用
rand()?因为rand()生成的是伪随机数,可预测性强,完全不适合密钥生成;而/dev/urandom和CryptGenRandom是加密安全的随机源,和Python的secrets模块逻辑完全对应。 - 每个
uint512类型变量占64字节,正好存储512位数据,和你Python里secrets.token_bytes(64)生成的结果完全匹配。
内容的提问来源于stack exchange,提问作者hch
相关产品推荐
相关产品推荐

