C 在这个例子中,我需要考虑字节数吗?
我正在编写一个加密/解密算法,从文件中读取字节块,执行我的魔术,然后将这些块写回文件。 我的算法的一部分使用一个并集。我将字节填充到bytes\u io字段中,然后再次从words\u io字段中取出字节,并应用一些uint32位掩码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
union {
uint32_t words_io[GKO_BLOCK_SIZE / sizeof(uint32_t)];
uint8_t bytes_io[GKO_BLOCK_SIZE];
} transformOut;
我假设(也是我的问题),我不必担心平台端序会影响我从union的单词字段中吸出的单词,因为union实际上只存储我首先插入的字节流(并且不会根据访问情况对它们重新排序)
我说得对吗?恐怕你的假设不正确:
- 从输入读取的字节以及存储联合体的
字段的方式,在以4块为单位读取时,将被视为bytes\u io
值,这肯定会受到系统端性的影响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()
。这对big endian系统来说是不可行的。或者,如果endianness与指定的默认值不同,可以使用其他方法测试endianness,并使用htonl()
bswap32()
- 在
数组上应用密码进行加密或解密单词\u io
- 以相反的方式应用字节交换,使用
或其他适当的方式htonl()
- 从
数组中输出字节bytes\u io
words\u io
元素执行ntohl()
,然后再执行@chqrlie指出的htontl()
来解决问题。这应该可以解决持久性问题。好的,谢谢。这就是我害怕的。如果我简单地将指向字节数组的指针转换为指向int32的指针,然后每4个字节遍历一次应用XOR的数组怎么样?@luket:没有区别,事实上,由于严格的别名规则,两种方法都调用未定义的行为。使用union
可以与gcc一起工作,因为这个编译器明确地允许通过union进行类型修剪,但是官方的方法是使用memcpy
。在这里检查我的想法。因为网络字节顺序是唯一的常量,所以我始终可以通过ntohl()将从单词_io[]提取的单词转换为网络字节顺序。我总是在读字节:所以我从磁盘上读到:“你好,世界,这是一个阳光明媚的日子”,然后加密,然后从words_io[]中提取单词,然后执行ntohl(),然后进行我的转换。解密程序运行并读取:加密的字节忽略当前机器进入字节缓冲区的endianness。我们可以再次从words_io[]中提取字节,然后再次执行ntohl(),将其转换为已知常量(进行解密变换)。这是否有效?谢谢chqrlie,您帮了大忙。