1
4
一些 密码算法,特别是哈希函数(在HMAC中使用),被指定在任意比特序列上操作。然而,在实际的物理计算机和大多数协议中,数据是 八位字节 :位数是8的倍数,可以按8位分组处理。一组8位在名义上是一个“八位字节”,但术语“字节”更常见。八位字节的数值介于0和255之间(含0和255)。在一些编程语言(例如Java)中,数值是在(128和127之间)签名的,但这是相同的概念。
注意,在C编程语言的上下文中(如ISO 9899:1999标准中的定义,即“C标准”),a
字节
被定义为基本可寻址存储器单元,由
因此,每一个在任意比特序列上工作的加密算法实际上都定义了如何将比特内部解释为八位字节(bytes)。这个 AES 和 SHA 即使在挑剔的数学家眼中,规范也要花很长的时间才能正确地做到这一点。对于每一个实际情况,您的数据都已经是一个字节序列,并且假定已经发生了将位分组为字节的情况;所以您只需将字节输入到算法实现中,一切都很好。 因此,在实践中,密码算法 实施 期望一个序列 字节 作为输入,并生成 字节 作为输出。 终结性 (隐含在字节级别)是关于多字节值(需要对多个字节进行编码的值)如何排列成字节序列(即哪个字节排在第一位)的约定。UTF-8是尾数中性的,因为它已经定义了这种布局:当一个字符要编码成几个字节时,UTF-8要求这些字节中的哪一个是第一个,哪一个是最后一个。这就是为什么utf-8是“endian中性的”:字符到字节的转换是一个固定的约定,这不取决于本地硬件最喜欢读取或写入字节的方式。endianness通常与整数值在内存中的写入方式有关。 关于跨平台编程: 经验是无法替代的。因此,在多个平台上尝试是一种好方法。通过使代码64位干净,即在32位和64位平台上正确运行相同的代码,您已经学到了很多东西。任何最近使用Linux的PC都能满足这个要求。现在,big-endian系统非常罕见;您需要一个较旧的Mac(一个带有PowerPC处理器的Mac)或几种Unix工作站中的一个(请记住SPARC系统或HP/UX下的Itanium系统)。较新的设计倾向于采用小endian约定。 关于c中的endianness: 如果你的程序必须要担心结尾,那么很可能你做的不对。endianness是关于将整数(16位、32位或更多)转换为字节并返回。如果您的代码担心endianness,那么这意味着您的代码以整数形式写入数据,并以字节形式读取数据,反之亦然。不管怎样,您都在做一些“类型别名”:内存的某些部分是通过不同类型的多个指针访问的。这是 坏的 。它不仅降低了代码的可移植性,而且在要求编译器优化代码时,它也容易崩溃。 在适当的C程序中,只有当值要写入或从文件或网络套接字中读取时,才会为I/O处理endianness。I/O遵循定义要使用的endianness的协议(例如,在TCP/IP中,通常使用big endian约定)。正确的方法是编写一些包装函数:
可能,使这些功能
然后,每当您想从一个新获得的(或即将写入的)文件或套接字的内存缓冲区中写入或读取32位整数时,都可以使用这些函数。这将使您的代码结束语中性(因此是可移植的),更清晰,从而更容易阅读、开发、调试和维护。而且在 非常罕见 在这种编码和解码成为瓶颈的情况下(只有在使用CPU非常弱、网络连接非常快的平台(即完全不是PC)时,才可能发生这种情况),您仍然可以用特定于体系结构的宏(可能是WI)替换这些功能的实现。不修改其余代码的内联程序集。 |
2
7
UTF-8字符串和STD::字符串都被定义为字符序列。加密算法被定义为对字节/八位字节序列进行操作(在C字节中,A字符是相同的,如果您的字节不是八位字节,那么您正在执行一个异常的实现,您可能需要稍微小心处理UTF-8)。在连续内存中表示一个字节序列的唯一合理方法是,第一个字节在最低地址,随后的一个字节在更高的地址(C数组)。加密算法不关心字节代表什么,所以没关系。
只有当你处理像
在实践中,如果您(可能通过您调用的某个东西)将char*重新解释为int*或反之亦然,或者定义一个协议,在该协议中,int使用一系列chars表示,那么endian ness在c中很重要。如果您只处理字符数组,或者只处理整数数组,那么这是不相关的,因为 endianness是ints的一个属性 以及其他比char大的类型。 |
3
2
似乎真正的问题是: “我能确定我编码的utf-8字符串在不同的计算机上将以相同的方式在内部表示吗?” 因为,正如您所说,OpenSSL例程并没有真正解决这个问题(它们也不必知道)。 因为你只要求评论,我认为你应该没事。无论计算机体系结构如何,对于两个相同的数据块,OpenSSL例程的行为应该相同。 |
4
0
一种确保endianes的方法是遵循IP标准 network byte order . 看一看 here 对于您需要的功能。这些应该在Windows和*NIX上可用现代C++实现。 不过,我相信你的推理是正确的,在这种情况下你不必担心。 编辑:为了清楚起见,网络字节顺序注释假定您正在发送数据,并且担心在另一端如何接收数据。如果发送和接收都在同一台机器上,那么应该没有问题。 |
sid_com · 为条件OO模块加载编写包装器模块的正确方法是什么? 10 年前 |
tssch · 获取用户名的可移植方式 11 年前 |
Prof. Falken · 如何编写(可移植的)反向网络字节顺序? 11 年前 |