在 c 中将字符数组转换为 uint32_t 数组——这是正确的方法吗?

Converting array of characters to an array of uint32_t in c-- is this the proper way?

我正在尝试将字符数组转换为 uint32_t 数组,以便在 CRC 计算中使用它。我很好奇这是这样做的正确方法还是危险的?我有进行危险转换的习惯,我正在努力学习更好的方法来转换危险性较小的东西 :)。我知道数组中的每个字符都是 8 位。我应该将 4 个字符相加并将其放入 unsigned int 数组的索引中,还是将每个字符放在其单独的数组中?将四个 8 位字符相加会将它们的值更改为数组吗?我读过一些关于移动字符的内容,但是,我不确定如何将四个字符移动到 unsigned int 数组的一个索引中。

text[i] 是我的字符数组。

uint32_t inputText[512];
for( i = 0; i < 504; i++)
{
  inputText[i] = (uint32_t)text[i];
}

演员表看起来不错;虽然,我不确定当 uint32_ts 的数组是 512 时为什么要说 i < 504。(如果你只想转换 504 个值并且你想要一个 512 长度的数组,你可能想要使用 array[512] = {0} 来确保内存被清零,而不是将最后 8 个值设置为内存中之前的任何值。)尽管如此,说 SomeArrayOfLargerType[i] = (largerType_t)SomeArrayOfSmallerType[i] 是完全安全的,但请记住现在怎么样了,你的二进制文件最终看起来像这样:

 0100 0001 -> 0000 0000 0000 0000 0000 0000 0100 0001

因此,这 24 个前导 0 可能是不希望出现的结果。

至于四个字的总结,那几乎肯定不是你想要的;除非你真的想要像 0000 0001(一)+ 0000 0010(二)= 0000 0100(三)这样的总和。如果您希望前面的示例生成 00000001 000000010,那么是的,您需要应用班次。

更新 - 一些关于通过示例进行转换的信息:

以下是移位的示例:

uint32_t valueArray[FINAL_LENGTH] = {0};
int i;
for(i=0; i < TEXT_LENGTH; i++){ // text_length is the initial message/text length (512 bytes or something)
    int mode = i % 4; // 4-to-1 value storage ratio (4 uint8s being stored as 1 uint32)
    int writeLocation = (int)(i/4); // values will be truncated, so something like 3/4 = 0 (which is desired)
    switch(mode){
        case(0):
            // add to bottom 8-bits of index
            valueArray[writeLocation] = text[i];
            break;
        case(1):
            valueArray[writeLocation] |= (text[i] << 8); // shift to left by 8 bits to insert to second byte
            break;
        case(2):
            valueArray[writeLocation] |= (text[i] << 16); // shift to left by 16 bits to insert to third byte
            break;
        case(3):
            valueArray[writeLocation] |= (text[i] << 24); // shift to left by 24 bits to insert to fourth byte
            break;
        default:
            printf("Some error occurred here... If source has been modified, please check to make sure the number of case handlers == the possible values for mode.\n");
    }
}

您可以在此处查看 运行 的示例:https://ideone.com/OcDMoM请注意,在 IDEOne 上执行该操作时会出现一些运行时错误。我没有仔细寻找但是,这个问题,因为输出似乎仍然是准确的,代码只是作为示例。)

本质上,因为每个字节都是 8 位,并且您希望将字节存储在 4 字节块(每个块 32 位)中,所以您需要四种不同的情况来确定移动的距离。在第一种情况下,前 8 位由消息中的一个字节填充。在第二种情况下,第二个 8 位由消息中的后续字节填充( 左移 8 位,因为这是二进制位置 的偏移量)。然后继续剩下的 2 个字节,然后从初始消息数组的下一个索引开始重复。

合并字节时,使用 |=,因为这将获取 uint32 中已有的内容,并将对其执行按位或运算,因此最终值将合并为一个值。

所以,为了分解一个简单的例子,比如我在最初的 post 中的例子,假设我有 0000 0001(一个)和 0000 0010(两个),还有一个用于保存它们的初始 16 位整数 0000 0000 0000 0000。第一个字节分配给 16 位整数,使其成为 0000 0000 0000 0001。然后将第二个字节左移 8 位,使其成为 0000 0010 0000 0000。最后,两者通过按位或,则16位整数变为:0000 0010 0000 0001.

对于一个32位的整数来容纳4个字节,这个过程会再重复2次,加上8个额外的移位,然后进入下一个uint32重复这个过程。

希望一切都有意义。如果没有,我可以尝试进一步澄清。