我想编写一个加密应用程序,需要一个函数来创建一个iv。创建iv我想使用rand()(即使这不安全,我想稍后重写代码的大部分内容)。这导致我的问题:rand()只返回从0到RAND_MAX的值(在我的机器上RAND_MAX是32767),我不知道如果RAND_MAX> = 65535我是否可以使用这样的代码:
void generate_iv(unsigned char* char_buf, int len){
union { //treat char_buf like a short_buf
unsigned char* char_buf;
unsigned short* short_buf;
}
int i;
for (i = 0; i < len / 2; i++){ //fill short_buf with random values
short_buf[i] = (unsigned short) rand();
}
if (len & 0x01){ //could not fill char_buf with 2-byte short values completely
char_buf[len - 1] = (unsigned char) rand();
}
}
当然,这将在每台机器上轻松编译,但它不适用于RAND_MAX&lt; 65535,因为那时函数没有填满每一位。
始终有效的代码是:
void generate_iv(unsigned char* char_buf, int len){
int i;
for (i = 0; i < len; i++){
char_buf = (unsigned char) rand();
}
}
此代码应该没有问题,但它不如上面的代码有效。 我的问题是:在这种情况下,在效率和可移植性之间是否存在任何最佳效果,是否可能有更多的方法(可能很容易实现)产生随机数或获得具有恒定大小的随机数?
答案 0 :(得分:2)
正如您所提到的那样,rand()
并不安全,所以无论出现什么问题,我都会参考手头的问题。
鉴于rand()
生成一个15位数字,并且您想要一个16位数字,您只需执行以下操作:
int a = rand();
int b = rand()&1;
return a | (b<<15);
或者通常,假设RAND_MAX < 0xFFFF
且RAND_MAX+1
是2的幂:
int len = BIT_LEN(RAND_MAX);
int mask = (1<<(16-len))-1;
int a = rand();
int b = rand()&mask;
return a | (b<<len);
顺便说一下,不要忘记在程序开头用一些随机输入为RNG播种,例如:
srand((unsigned int)time(NULL));