如何用rand()替代/dev/urandom?Ubuntu环境代码适配问题
让我来帮你排查下问题,顺便给出能正常工作的替代实现~
你的两种写法为啥失败?
第一种写法的问题
- 你直接
malloc了buf,但原函数的设计是调用者负责提前分配好buf的内存,然后把指针传给函数填充数据。如果这段代码是在某个函数内部写的,你并没有把malloc后的buf指针返回给调用者,调用者根本拿不到生成的随机数据; - 大概率你忘记初始化随机数生成器了——
rand()在第一次调用前必须用srand()设置种子,不然每次程序运行都会生成完全相同的随机序列,这也会导致你觉得“程序运行失败”; - 另外,
rand()返回的是int类型(通常是32位),直接赋值给unsigned char会自动截断成8位,这在测试场景没问题,但最好明确处理,可读性更强。
第二种写法的问题
- 最核心的bug:函数参数
unsigned char *buf是值传递,你在函数里给buf = malloc(...)只是修改了函数内部的形参地址,完全不会影响调用者那边传入的实参指针。调用者的buf还是原来的地址,自然拿不到你生成的数据; - 同样存在没有初始化
srand()的问题。
正确的替代实现
要和原函数的接口行为保持一致,需要注意两个关键点:
- 必须在程序启动时调用一次
srand()初始化随机数生成器; - 直接使用调用者传入的buf填充数据,不要在函数内重新分配内存。
#include <stdlib.h> #include <time.h> // 程序初始化时调用一次,比如放在main函数开头 void init_random() { srand((unsigned int)time(NULL)); } // 和原函数接口完全兼容的替代版本 int randomBytes(unsigned char *buf, const int num) { // 先做参数合法性检查,和原函数的错误处理逻辑对齐 if (buf == NULL || num <= 0) { return -1; } for (int i = 0; i < num; i++) { // 明确取rand()的低8位,等价于直接赋值,但可读性更好 buf[i] = (unsigned char)(rand() & 0xFF); } return 0; }
使用说明
- 一定要先调用
init_random(),不然每次运行程序都会生成一模一样的“随机”字节; - 调用
randomBytes前,你需要像原函数那样,提前分配好足够大小的buf(比如unsigned char *my_buf = malloc(100);),然后把指针传进去; - 正如你提到的,这个实现只适合测试验证,
rand()不是加密安全的,绝对不能用于加密相关场景。
内容的提问来源于stack exchange,提问作者augre
相关产品推荐
相关产品推荐

