【问题标题】:Sizeof and StrlenSizeof 和 Strlen
【发布时间】:2014-06-21 16:41:27
【问题描述】:

我正在尝试使用 Salt 和密码实现加密。因为推荐的 Salt 大小是 64 位,所以我声明了。

char Salt[8];

我使用 RAND_pseudo_bytes 以这种方式获得随机盐:

RAND_pseudo_bytes((unsigned char*)Salt, sizeof Salt);

而且因为每次编译时 hexdump 输出的长度都不同(有时是 5 个,主要是 24 个字节),因为我错误地使用了 sizeof 的 strlen 插入:

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 让我觉得很奇怪。谢谢。

【问题讨论】:

  • 大概是因为您没有以 null 结尾的字符串,所以您正在调用 未定义的行为

标签: c++ sizeof strlen


【解决方案1】:

strlen 将沿着你给它的指针向下移动并计算字节数,直到它到达一个空字节。在这种情况下,您的 8 字节 char 数组没有空字节,因此 strlen 愉快地继续越过边界进入堆栈上定义的 char 数组之外的内存区域,并且发生的任何事情都将决定 @ 的行为987654323@。在这种情况下,在数组开头的 24 个字节之后,有一个空字节。

【讨论】:

    【解决方案2】:
    1. 不要使用char 来表示字节。
    2. 一个字节的一半以上的值是不可打印的,即它们没有对应的可打印值。
    3. 我建议您使用printf("0x%02X\n", array[i]); 遍历uint8_t 的数组

    【讨论】:

      【解决方案3】:

      strlen()搜索第一个空字符并计算除该空字节之外的所有字节。 盐是 8 个非零字节 - 不能保证下一个字符是空字节。

      这就是 sizeof 和 strlen 不同的原因。

      【讨论】:

      • 我什至错了:盐也可以包含值为零的字节,所以中间的零会导致 strlen() 返回太少...
      【解决方案4】:

      sizeof 是一个运算符,它返回存储特定数据结构所需的字节数。当应用于一个字符数组时,它代表了三种情况,其中数组的名称不会衰减到指向其第一个元素的指针(另外两种是 & 的使用和通过字符串字面量进行的初始化)。

      strlen 是一个函数,假设它的输入是一个以空字符结尾的字符序列。因为当您将字符数组的名称传递给函数时,它确实会衰减到其第一个元素的指针,strlen 无法知道原始数据结构的大小(就像 sizeof 一样)。它得到的只是一个指向 char 的指针。它可以确定字符串结尾的唯一方法是遍历字符序列,寻找'\0'。在您的情况下,它在内存中的第 24 个字节之前找不到一个。这纯属偶然。

      尝试使用以下方法初始化您的数组:

      char Salt[8] = {0};
      

      并确保您的 RAND_pseudo_bytes 函数在处理过的字符串中保留标记“\0”。

      【讨论】:

        【解决方案5】:

        除了salt的空终止,正如其他人指出的那样,您需要将printf中的格式说明符更改为%zu,因为strlen返回类型是size_t。使用错误的说明符会调用未定义的行为

        【讨论】:

          【解决方案6】:

          解决您关于strlen()的问题

          strlen() 计算的是内存中第一个 '\0' 之前的字节数。

          char Salt[9] = { '\0' };
          

          将使用所有'\0's 初始化Salt


          注意:正如@OliCharlesworth 所指出的,Salt 可以嵌入 NULL。不要使用任何str*() 方法。您只需要使用mem*() 方法并自己跟踪长度。不要依赖sizeof,因为数组在传递给函数时会变成指针。

          【讨论】:

          • 即使这样也不一定有效;一组随机字节不是字符串;它本身可以包含 0 值字节。
          猜你喜欢
          • 2012-04-13
          • 1970-01-01
          • 1970-01-01
          • 2017-12-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多