服装移动网站策划案怎么做盗文网站

当前位置: 首页 > news >正文

服装移动网站策划案,怎么做盗文网站,网站建设课程心得,谷歌chrome浏览器端序#xff08;Endianness#xff09;#xff0c;又称字节顺序#xff0c;又称尾序#xff0c;在计算机科学领域中#xff0c;指存储器中或在数字通信链路中#xff0c;组成多字节的字的字节的排列顺序。 在几乎所有的机器上#xff0c;多字节对象都被存储为连续的字…端序Endianness又称字节顺序又称尾序在计算机科学领域中指存储器中或在数字通信链路中组成多字节的字的字节的排列顺序。 在几乎所有的机器上多字节对象都被存储为连续的字节序列。例如在C语言中一个类型为int的变量x地址为0x100那么其对应地址表达式x的值为0x100。且x的四个字节将被存储在存储器的0x100, 0x101, 0x102, 0x103位置。 计算机硬件的字节的排列方式有两个通用规则 大端序Big-endian将数据的低位字节存放在内存的高位地址高位字节存放在低位地址。这种排列方式与数据用字节表示时的书写顺序一致符合人类的阅读习惯。小端序Little-Endian将一个多位数的低位放在较小的地址处高位放在较大的地址处则称小端序。小端序与人类的阅读习惯相反但更符合计算机读取内存的方式因为CPU读取内存中的数据时是从低地址向高地址方向进行读取的。因为计算机电路先处理低位字节效率比较高因为计算都是从低位开始的。所以计算机的内部处理都是小端字节序。 在计算机内部小端序被广泛应用于现代 CPU 内部存储数据而在其他场景符合人类的习惯还是读写大端字节序所以除了计算机的内部处理其他的场景下几乎都是大端字节序比如网络传输和文件存储。 在网络应用中字节序是一个必须被考虑的因素因为不同机器类型可能采用不同标准的字节序所以均按照网络标准转化。例如假设上述变量x类型为int位于地址0x100处它的值为0x01234567地址范围为0x100~0x103字节其内部排列顺序依赖于机器的类型。大端序从首位开始将是0x100: 0x01, 0x101: 0x23, 0x102: 0x45, 0x103: 0x67。而小端序将是0x100: 0x67, 0x101: 0x45, 0x102: 0x23, 0x103: 0x01。 上面的文字描述有点抽象举个例子 大端序 //对于一个整数 0x12345678在内存中的存储顺序是: 地址: 0 1 2 3 数据: 12 34 56 78//网络协议通常采用大端序例如TCP/IP。小端序: //对于一个整数 0x12345678在内存中的存储顺序是 地址: 0 1 2 3 数据: 78 56 34 12//大多数现代PC如x86架构使用小端序。在内存中存放整型数值168496141 需要4个字节这个数值的对应的16进制表示是0X0A0B0C0D这个数值在用大端序和小端序排列时的在内存中的图示更易于理解
字节序的作用 了解字节序对于数据存储和处理非常重要理解字节序有助于调试跨平台应用和网络协议。在数据处理时在不同字节序的系统间传输数据时需转换字节序以确保正确性。 由于计算机处理字节序的时候不知道什么是高位字节什么是低位字节。它只知道按顺序读取字节先读第一个字节再读第二个字节。如果是大端字节序先读到的就是高位字节后读到的就是低位字节。小端字节序正好相反。 字节序的处理只有读取的时候才必须区分字节序其他情况都不用考虑。 处理器读取外部数据的时候必须知道数据的字节序将其转成正确的值。然后就正常使用这个值完全不用再考虑字节序。即使是向外部设备写入数据也不用考虑字节序正常写入一个值即可。外部设备会自己处理字节序的问题。 将数据的外部格式 文件格式、网络协议、硬件寄存器转换为内部格式 软件操作的数据结构的过程实际上比你想象的要困难得多。黑客利用的软件漏洞大多也是由于解析错误造成的。由于程序员没有正式学习解析他们自己摸索创建了容易出错的临时解决方案。例如程序员假设外部缓冲区不能大于内部缓冲区从而导致缓冲区溢出。 因此 外部格式必须定义明确。第一个字节的含义必须写在某处然后是第二个字节的含义依此类推。 假如说传递或存储一个整数定义必须包括大小、有符号/无符号、位的含义几乎总是 2 的补码和字节顺序。超过取值范围0~255的整数则必须用多个字节表示。这些字节是从左到右还是从右到左称为字节顺序。 我们也称之为字节序一种形式是大端序 另一种形式是小端序。 在 1970 年代当 CPU 只有几千个逻辑门时小端序对于逻辑电路来说可以更高效。因此许多内部处理都是小端序的并且这也渗透到外部格式中。 另一方面大多数网络协议和文件格式仍然是大端序的。因为格式规范是为人类理解而编写的大端序对我们人类来说更容易阅读和理解。 因此一旦理解了外部格式中的字节顺序问题下一个问题就是弄清楚如何解析它将其转换为内部数据结构。首先我们必须要了解它是如何解析的 解析有两种方式缓冲或流式传输。 在缓冲模型中你首先读入整个输入例如整个文件或整个网络数据包然后解析它。在流式传输模式下你一次读取一个字节解析该字节然后读取下一个字节。流式传输模式最适合非常大的文件或跨 TCP 网络连接的流式传输数据。 缓冲解析是大多数人使用的一般方法。假设你已经将文件或网络数据读入我们称为buf的缓冲区。你在当前偏移量处解析该缓冲区 直到到达末尾。 假设如此我们在处理器中读入一个16位整数。如果是大端字节序就按下面的方式转成值。那么解析大端序 整数x 的方式 就是以下代码行 x buf[offset] * 256 buf[offset1];// buf是整个数据块在内存中的起始地址offset是当前正在读取的位置。第一个字节乘以256再加上第二个字节就是大端字节序的值。或者也可以使用逻辑运算符的形式进行改写则按以下方式执行 x buf[offset]8 | buf[offset1]; // 第一个字节左移8位即后面添8个0然后再与第二个字节进行或运算。编译器始终将 2 的幂乘法转换为移位指令因此两个语句都会执行相同的操作。某些编译器足够智能可以将此模式识别为解析整数并且可能会将其替换为从内存中加载两个字节并进行字节交换。 对于外部数据中的小端序整数你可以反转解析方式例如以下两个语句之一。 x buf[offset1] * 256 buf[offset]; x buf[offset] buf[offset1] * 256;32位整数的求值公式也是一样的 /* 大端字节序 / i (data[3]0) | (data[2]8) | (data[1]16) | (data[0]24);/ 小端字节序 */ i (data[0]0) | (data[1]8) | (data[2]16) | (data[3]24);对于 JavaScript、C# 或其他一些语言而言关于字节序的讨论到此就结束了。但如果你使用的是 C/C我们还需要处理一些额外的问题。因为 C 的问题在于它是一种低级语言。这意味着它向程序员公开了整数的内部格式。换句话说上面的代码关注整数的外部表示而不关心内部表示。它并不关心你使用的是 x86 小端序 CPU 还是某些 RISC 大端序 CPU。 但在 C语言 中你可以依靠内部 CPU 表示来解析整数。它看起来类似于以下内容 x (short)(buf offset);这段代码在小端序机器和大端序机器上产生了不同的结果。 如果两个字节分别为 0x22 和 0x11那么在大端序机器上会产生一个值为0x2211的短整数但小端序机器会产生值为0x1122。如果外部格式是大端序那么在小端序机器上你必须对结果进行字节交换。 那么代码看起来像是 x (short)(buf offset);#ifdef LITTLE_ENDIANx (x 8) | ((x 0xFF) 8);#endif当然我们不会这样写代码。相反你应该使用宏如下所示 x ntohs((short)(buf offset));该宏表示network-to-host-short其中 网络 字节序为大端字节序主机 字节序未定义。在小端字节序主机 CPU 上字节交换方式如上所示。在大端字节序 CPU 上该宏未定义任何内容。该宏在标准套接字库如 arpa/inet.h中定义。其他库中还有大量用于字节交换整数的类似宏。 事实上这并不是真正的做法一次解析一个整数。相反程序员要做的是定义一个与 他们试图解析的外部格式相对应的 打包 C 结构然后将 缓冲区 转换为该 结构。 例如在 Linux 中包含文件netinet/ip.h定义了Internet协议头 struct ip { #if BYTE_ORDER LITTLE_ENDIAN u_char ip_hl:4, / 请求头长度 /ip_v:4; / 版本 / #endif #if BYTE_ORDER BIG_ENDIAN u_char ip_v:4, /版本/ip_hl:4; /*请求头长度 / #endifu_char ip_tos; / 服务类型 /short ip_len; / 总长度 /u_short ip_id; / 标识*/short ip_off; /片段偏移量字段/u_char ip_ttl; /*生存时间 /u_char ip_p; / 协议 /u_short ip_sum; / 校验和* /struct in_addr ip_src,ip_dst; / 源和目标地址 / };要“解析”协议头需要执行以下操作 strict ip *hdr (struct ip *)buf;printf(checksum 0x%04x\n, ntohs(ip-ip_sum));这被认为是“优雅”的执行方式因为根本没有“解析”。在 big-endian CPU 上它也是一个无操作——它精确地花费零指令来“解析”协议头因为内部和外部结构都完全映射。 然而在 C 中结构的确切格式未定义。结构成员之间通常会有填充以使整数在自然边界上对齐。因此编译器有指令将结构声明为“packed”以摆脱这种填充这严格定义内部结构以匹配外部结构。 然而这是错误的做法。因为它仅仅在 C 中是可能的但这并不代表它是个好主意。 有些人认为它的效率可以更快。它并不是真的更快了。如今即使是低端 ARM CPU 也非常快深度管道也带来了多重问题。决定其速度的往往是分支预测错误和长链依赖性等因素。指令数量几乎是事后才考虑的。因此在外部数据之上“零开销”映射结构与一次解析一个字节之间的性能优化差异几乎是无法估量的。 另一方面存在“正确性”成本。C 语言中没有定义强制转换整数的结果正如上例所示。所以这里有一个笑话提到“可以接受擦除整个硬盘的行为却不是返回预期的两字节数字。” 在现实世界中未定义的代码会导致编译器问题因为它们试图优化问题。有的时候重要的代码行会从程序中删除因为编译器严格解释 C 语言 标准的规则。在 C 中使用未定义的行为确实会产生未定义的结果——与程序员的预期完全相反。 一次解析一个字节的结果是定义的。转换整数和结构的结果不是。因此应该避免这种做法。它使编译器感到困惑。它使试图验证代码正确性的静态和动态分析器感到困惑。 此外实际问题是转换这些东西会让程序员感到困惑。程序员 相当了解解析外部格式但混合内部/外部字节序会导致无尽的混乱。它会导致有缺陷的代码无穷无尽。 它会导致屎山代码无穷无尽。许开源代码中同样是如此以正确方式解析整数的代码始终比使用ntohs()等宏的代码更容易阅读。这样的代码混乱且容易出现各种问题困惑的程序员不断地来回交换整数不理解到底发生了什么并且只要函数的输入顺序错误就简单地添加另一个字节交换。 所以字节序也是一个解析器问题处理外部数据格式/协议。在 C/C 中处理它的方式与在 JavaScript、C# 或任何其他语言中相同。这样的处理方式是最优的。 还有一种字节序的错误方式这是 C/C 中的 CPU 问题将内部和外部结构混合在一起交换字节。多年以来这造成了无尽的麻烦。 所以我们也需要停止旧方法并采用新方法。 在C语言中实现大端序和小端序的转换可以使用按位操作 #include stdio.h// 交换端序的函数 unsigned int swap_endian(unsigned int num) {return ((num 24) 0xFF) | // 将 字节3 移动到 字节0((num 8) 0xFF0000) | // 将 字节1 移动到 字节2((num 8) 0xFF00) | // 将 字节2 移动到 字节1((num 24) 0xFF000000); // 将 字节0 移动到 字节3 }int main() {unsigned int original 0x12345678;unsigned int swapped swap_endian(original);printf(Original: 0x%x\n, original);printf(Swapped: 0x%x\n, swapped);return 0; }//使用移位和按位与操作将各字节重新排列 //应用场景 // 在需要处理不同字节序的数据时使用比如网络通信或文件读写。了解字节序的意义 了解字节序的意义在于确保数据在不同计算机系统之间能够正确地传输和解释。字节序决定了多字节数据类型如整数、浮点数在内存中的存储顺序。 跨平台兼容性问题不同系统可能使用不同的字节序了解字节序可以避免跨平台数据传输中的错误在网络通信中网络协议通常采用大端序网络字节序需要在发送和接收数据时进行转换。在数据存储中在文件中存储多字节数据时使用一致的字节序可以确保在不同平台上读取时一致。对开发人员而言知道系统的字节序在调试开发低级别代码时能够理解数据的内存布局。 理解和正确处理字节序是系统编程、网络编程和跨平台开发中的一个重要环节。 正因为以上种种原因所以才有了字节序。 我们在阅读代码时也不需要搞得这么底层大部分时候我们只需要知道计算机处理字节序的时候如果是大端字节序先读到的就是高位字节后读到的就是低位字节。小端字节序则正好相反。 以上。 我是一个十分热爱技术的程序员希望这篇文章能够对您有帮助也希望认识更多热爱程序开发的小伙伴。 感谢