C 在这个例子中,我需要考虑字节数吗?

C 在这个例子中,我需要考虑字节数吗?,c,endianness,unions,C,Endianness,Unions,我正在编写一个加密/解密算法,从文件中读取字节块,执行我的魔术,然后将这些块写回文件。 我的算法的一部分使用一个并集。我将字节填充到bytes\u io字段中,然后再次从words\u io字段中取出字节,并应用一些uint32位掩码 union { uint32_t words_io[GKO_BLOCK_SIZE / sizeof(uint32_t)]; uint8_t bytes_io[GKO_BLOCK_SIZE]; } tra

我正在编写一个加密/解密算法,从文件中读取字节块,执行我的魔术,然后将这些块写回文件。 我的算法的一部分使用一个并集。我将字节填充到bytes\u io字段中,然后再次从words\u io字段中取出字节,并应用一些uint32位掩码

union {
    uint32_t words_io[GKO_BLOCK_SIZE / sizeof(uint32_t)];
    uint8_t bytes_io[GKO_BLOCK_SIZE];                       
} transformOut;
我假设(也是我的问题),我不必担心平台端序会影响我从union的单词字段中吸出的单词,因为union实际上只存储我首先插入的字节流(并且不会根据访问情况对它们重新排序)


我说得对吗?

恐怕你的假设不正确:

  • 从输入读取的字节以及存储联合体的
    bytes\u io
    字段的方式,在以4块为单位读取时,将被视为
    int32\u t
    值,这肯定会受到系统端性的影响
例如,假设您的加密技术是一个简单的独占或应用于
words\u io
成员的元素。除非密钥恰好是对称的endian,否则xor运算的结果在小endian系统和大endian系统上是不同的。在big-endian手机上应用此密码与在接收加密信息的little-endian PC上运行的相同代码不兼容

如果您的密码使用
int32\t
数组,则必须采取以下步骤:

  • 将输入字节读入
    bytes\u io
    块,并用
    GKO\u block\u SIZE
    字节的适当值填充
  • 应用字节交换对
    单词\u io
    数组中的所有单词强制执行指定的尾数。例如,读取后使用
    ntohl()
    ,写入字节前使用
    htonl()
    。这对big endian系统来说是不可行的。或者,如果endianness与指定的默认值不同,可以使用其他方法测试endianness,并使用
    bswap32()
  • 单词\u io
    数组上应用密码进行加密或解密
  • 以相反的方式应用字节交换,使用
    htonl()
    或其他适当的方式
  • bytes\u io
    数组中输出字节

如果您将加密文件读取到具有不同端号的平台上,则会产生不同的效果。否则,请停止。帮我理解。如果我从一个文件中读取一个字节块,比如512字节。在这一点上endianness不是问题,对吗?如果我接着memcpy()将字节放入union字段bytes_io,endianness仍然不起作用。如果我从words_io中提取一个单词,说words_io[0],你是说endianness将发挥作用,平台将重新排列字节?如果这是为了跨平台工作,是的,这很重要。-->我怀疑这种担心是没有根据的。问题是什么?@luket根据您使用的库,它应该自己解决持久性问题。如果不是,并且您可以访问代码,您可以在加密/解密之前对每个
words\u io
元素执行
ntohl()
,然后再执行@chqrlie指出的
htontl()
来解决问题。这应该可以解决持久性问题。好的,谢谢。这就是我害怕的。如果我简单地将指向字节数组的指针转换为指向int32的指针,然后每4个字节遍历一次应用XOR的数组怎么样?@luket:没有区别,事实上,由于严格的别名规则,两种方法都调用未定义的行为。使用
union
可以与gcc一起工作,因为这个编译器明确地允许通过union进行类型修剪,但是官方的方法是使用
memcpy
。在这里检查我的想法。因为网络字节顺序是唯一的常量,所以我始终可以通过ntohl()将从单词_io[]提取的单词转换为网络字节顺序。我总是在读字节:所以我从磁盘上读到:“你好,世界,这是一个阳光明媚的日子”,然后加密,然后从words_io[]中提取单词,然后执行ntohl(),然后进行我的转换。解密程序运行并读取:加密的字节忽略当前机器进入字节缓冲区的endianness。我们可以再次从words_io[]中提取字节,然后再次执行ntohl(),将其转换为已知常量(进行解密变换)。这是否有效?谢谢chqrlie,您帮了大忙。