我正在尝试使用Salt和Password实现加密。由于Salt的推荐大小是64位,我宣称。
char Salt[8];
我使用RAND_pseudo_bytes以这种方式随机获取Salt:
RAND_pseudo_bytes((unsigned char*)Salt, sizeof Salt);
因为每次编译时hexdump输出的长度不同(有时是5,大多是24字节),因为我错误地使用了sizeof的strlen instread:
RAND_pseudo_bytes((unsigned char*)Salt, strlen(Salt));
我尝试了以下一行来弄清楚发生了什么:
printf("\n%d\n",strlen(Salt));
每次输出24次。
所以,我的问题是:当我宣布Salt的长度为8(sizeof(Salt)= 8)时,为什么strlen(Salt)= 24?我会理解一个9(用' \ 0',虽然不完全确定这究竟会发生什么),但24让我觉得奇怪。谢谢。
答案 0 :(得分:3)
strlen
将沿着你给它的指针向下走,并计算字节数,直到它达到空字节。在这种情况下,8个字节的char数组没有空字节,因此strlen
愉快地继续经过边界进入堆栈上定义的char数组之外的内存区域,无论发生什么,都会确定行为strlen
。在这种情况下,超过数组开头的24个字节,就有一个空字节。
答案 1 :(得分:2)
char
来表示字节。uint8_t
printf("0x%02X\n", array[i]);
数组
醇>
答案 2 :(得分:1)
strlen()
搜索第一个空字符并计算除该空字节之外的所有字节。
salt是8个非零字节 - 并且不能保证下一个字符是空字节。
这就是sizeof和strlen不同的原因。
答案 3 :(得分:1)
sizeof
是一个运算符,它返回存储特定数据结构所需的字节数。当应用于一个字符数组时,它表示三种情况,其中数组的名称不会衰减到指向其第一个元素的指针(另外两个是&和通过字符串文字初始化的使用)。
strlen
是一个函数,假设它的输入是一个以null结尾的字符序列。因为当你将一个字符数组的名称传递给一个函数时,它会衰减到它的第一个元素的指针,strlen
无法知道原始数据结构的大小(就像sizeof那样)。它得到的只是一个指向char的指针。它可以确定字符串结尾的唯一方法是遍历字符序列,查找' \ 0'。在你的情况下,它在内存中的第24个字节之前找不到一个。这纯粹是偶然发生的。
尝试使用以下命令初始化数组:
char Salt[8] = {0};
并确保您的RAND_pseudo_bytes
功能保留了哨兵' \ 0'在处理过的字符串中。
答案 4 :(得分:0)
解决有关strlen()
strlen()
计算的是内存中第一个'\0'
之前的字节数。
char Salt[9] = { '\0' };
将使用所有Salt
初始化'\0'
。
注意:正如@OliCharlesworth所指出的,Salt可以嵌入NULL。不要使用任何str*()
方法。您只需要使用mem*()
方法并自己跟踪长度。不要依赖sizeof
因为数组在传递给函数时会变成指针。
答案 5 :(得分:0)
除了salt
的空终止,正如其他人指出的那样,您需要将printf
中的格式说明符更改为%zu
,因为strlen
返回类型为{{1} }}。使用错误的说明符调用未定义的行为。