📜  位操作|交换数字的字节序

📅  最后修改于: 2021-04-24 22:14:52             🧑  作者: Mango

先决条件: https : //www.geeksforgeeks.org/little-and-big-Endian-mystery/

Little Endian和Big Endian是在机器中存储数据的方式。一些机器可能使用Little Endian字节顺序,而其他机器可能使用big Endian。当您将数据从Big Endian机器传输到Little Endian机器时,这会导致不一致。通常,编译器负责转换。但是,在网络中,Big Endian被用作网络之间数据交换的标准。因此,Little Endian机器需要在通过网络发送数据时将其数据转换为Big Endian。同样,Little Endian机器从网络接收数据时也需要交换字节顺序。

因此,当您通过网络从一台主机到另一台主机发送和接收数据时,Endianness就会成为现实。如果发送方计算机和接收方计算机具有不同的字节序,则需要交换字节序以使其兼容。

因此,重要的是将数据转换为小Endian或大Endian,以便保持一致性和数据完整性。在本文中,我们将研究如何交换数字的字节序。这也是一个常见的面试问题。

方法 :

  1. 通过将0x000000FF与之相加来获得数字的最右边8位,因为最后8位全为1,其余均为0,结果将为数字的最右边8位。结果存储在名为leftmost_byte的变量中
  2. 同样,通过将数字与0x0000FF00相乘来获得数字的后8位(从右到右)。结果存储在left_middle_byte中
  3. 通过将数字与0x00FF0000相乘来获得数字的后8位。结果存储在right_middle_byte中
  4. 最后,通过将数字与0xFF000000相加来获得数字的最左8位。结果存储在rightmost_byte中
  5. 现在我们已经拥有了数字的所有4个字节,我们需要以相反的顺序将其串联起来。即交换数字的字节序。为此,我们将最右边的8位向左移动24位,以使其成为最左边的8位。我们将右中间字节向左移16(以将其存储为左中间字节),将左中间字节向左移8(以将其存储为右侧混音字节)。最后,将最左边的字节向左移24。
  6. 现在,我们在逻辑上“或”(连接)所有变量以获得结果。

考虑数字0x12345678。该数字为4字节宽。在Big Endian中,此数字表示为:

Little Endian中,相同的数字表示为:

例子:

实施方式

C++
// C++ program to print the difference 
// of Alternate Nodes 
#include  
using namespace std;
  
// Function to swap a value from 
// big Endian to little Endian and 
// vice versa. 
int swap_Endians(int value) 
{ 
  
    // This var holds the leftmost 8 
    // bits of the output. 
    int leftmost_byte; 
  
    // This holds the left middle 
    // 8 bits of the output 
    int left_middle_byle; 
  
    // This holds the right middle 
    // 8 bits of the output 
    int right_middle_byte; 
  
    // This holds the rightmost 
    // 8 bits of the output 
    int rightmost_byte; 
  
    // To store the result 
    // after conversion 
    int result; 
  
    // Get the rightmost 8 bits of the number 
    // by anding it 0x000000FF. since the last 
    // 8 bits are all ones, the result will be the 
    // rightmost 8 bits of the number. this will 
    // be converted into the leftmost 8 bits for the 
    // output (swapping) 
    leftmost_byte = (value & 0x000000FF) >> 0; 
  
    // Similarly, get the right middle and left 
    // middle 8 bits which will become 
    // the left_middle bits in the output 
    left_middle_byle = (value & 0x0000FF00) >> 8; 
  
    right_middle_byte = (value & 0x00FF0000) >> 16; 
  
    // Get the leftmost 8 bits which will be the 
    // rightmost 8 bits of the output 
    rightmost_byte = (value & 0xFF000000) >> 24; 
  
    // Left shift the 8 bits by 24 
    // so that it is shifted to the 
    // leftmost end 
    leftmost_byte <<= 24; 
  
    // Similarly, left shift by 16 
    // so that it is in the left_middle 
    // position. i.e, it starts at the 
    // 9th bit from the left and ends at the 
    // 16th bit from the left 
    left_middle_byle <<= 16; 
  
    right_middle_byte <<= 8; 
  
    // The rightmost bit stays as it is 
    // as it is in the correct position 
    rightmost_byte <<= 0; 
  
    // Result is the concatenation of all these values. 
    result = (leftmost_byte | left_middle_byle |
              right_middle_byte | rightmost_byte); 
  
    return result; 
} 
  
// Driver Code 
int main() 
{ 
  
    // Consider a hexadecimal value 
    // given below. we are gonna convert 
    // this from big Endian to little Endian 
    // and vice versa. 
  
    int big_Endian = 0x12345678; 
    int little_Endian = 0x78563412; 
  
    int result1, result2; 
  
    result1 = swap_Endians(big_Endian); 
  
    result2 = swap_Endians(little_Endian); 
  
    printf("big Endian to little:"
           "0x%x\nlitle Endian to big: 0x%x\n",
            result1, result2); 
  
    return 0; 
} 
  
// This code is contributed by SHUBHAMSINGH10


C
#include 
  
// Function to swap a value from
// big Endian to little Endian and
// vice versa.
  
int swap_Endians(int value)
{
  
    // This var holds the leftmost 8
    // bits of the output.
  
    int leftmost_byte;
  
    // This holds the left middle
    // 8 bits of the output
  
    int left_middle_byle;
  
    // This holds the right middle
    // 8 bits of the output
  
    int right_middle_byte;
  
    // This holds the rightmost
    // 8 bits of the output
  
    int rightmost_byte;
  
    // To store the result
    // after conversion
  
    int result;
  
    // Get the rightmost 8 bits of the number
    // by anding it 0x000000FF. since the last
    // 8 bits are all ones, the result will be the
    // rightmost 8 bits of the number. this will
    // be converted into the leftmost 8 bits for the
    // output (swapping)
  
    leftmost_byte = (value & 0x000000FF) >> 0;
  
    // Similarly, get the right middle and left
    // middle 8 bits which will become
    // the left_middle bits in the output
  
    left_middle_byle = (value & 0x0000FF00) >> 8;
  
    right_middle_byte = (value & 0x00FF0000) >> 16;
  
    // Get the leftmost 8 bits which will be the
    // rightmost 8 bits of the output
  
    rightmost_byte = (value & 0xFF000000) >> 24;
  
    // Left shift the 8 bits by 24
    // so that it is shifted to the
    // leftmost end
  
    leftmost_byte <<= 24;
  
    // Similarly, left shift by 16
    // so that it is in the left_middle
    // position. i.e, it starts at the
    // 9th bit from the left and ends at the
    // 16th bit from the left
  
    left_middle_byle <<= 16;
  
    right_middle_byte <<= 8;
  
    // The rightmost bit stays as it is
    // as it is in the correct position
  
    rightmost_byte <<= 0;
  
    // Result is the concatenation of all these values.
  
    result = (leftmost_byte | left_middle_byle
              | right_middle_byte | rightmost_byte);
  
    return result;
}
  
// Driver Code
int main()
{
  
    // Consider a hexadecimal value
    // given below. we are gonna convert
    // this from big Endian to little Endian
    // and vice versa.
  
    int big_Endian = 0x12345678;
    int little_Endian = 0x78563412;
  
    int result1, result2;
  
    result1 = swap_Endians(big_Endian);
  
    result2 = swap_Endians(little_Endian);
  
    printf("big Endian to little: 0x%x\nlitle Endian to big: 0x%x\n",
           result1, result2);
  
    return 0;
}


Java
// Java program to print the difference 
// of Alternate Nodes 
import java.util.*;
  
class GFG
{
  
// Function to swap a value from
// big Endian to little Endian and
// vice versa.
static int swap_Endians(int value)
{
  
    // This var holds the leftmost 8
    // bits of the output.
    int leftmost_byte;
  
    // This holds the left middle
    // 8 bits of the output
    int left_middle_byle;
  
    // This holds the right middle
    // 8 bits of the output
    int right_middle_byte;
  
    // This holds the rightmost
    // 8 bits of the output
    int rightmost_byte;
  
    // To store the result
    // after conversion
    int result;
  
    // Get the rightmost 8 bits of the number
    // by anding it 0x000000FF. since the last
    // 8 bits are all ones, the result will be the
    // rightmost 8 bits of the number. this will
    // be converted into the leftmost 8 bits for the
    // output (swapping)
    leftmost_byte = (value & 0x000000FF) >> 0;
  
    // Similarly, get the right middle and left
    // middle 8 bits which will become
    // the left_middle bits in the output
    left_middle_byle = (value & 0x0000FF00) >> 8;
  
    right_middle_byte = (value & 0x00FF0000) >> 16;
  
    // Get the leftmost 8 bits which will be the
    // rightmost 8 bits of the output
    rightmost_byte = (value & 0xFF000000) >> 24;
  
    // Left shift the 8 bits by 24
    // so that it is shifted to the
    // leftmost end
    leftmost_byte <<= 24;
  
    // Similarly, left shift by 16
    // so that it is in the left_middle
    // position. i.e, it starts at the
    // 9th bit from the left and ends at the
    // 16th bit from the left
    left_middle_byle <<= 16;
  
    right_middle_byte <<= 8;
  
    // The rightmost bit stays as it is
    // as it is in the correct position
    rightmost_byte <<= 0;
  
    // Result is the concatenation of all these values.
    result = (leftmost_byte | left_middle_byle | 
              right_middle_byte | rightmost_byte);
  
    return result;
}
  
// Driver Code
public static void main(String[] args) 
{
    // Consider a hexadecimal value
    // given below. we are gonna convert
    // this from big Endian to little Endian
    // and vice versa.
    int big_Endian = 0x12345678;
    int little_Endian = 0x78563412;
  
    int result1, result2;
  
    result1 = swap_Endians(big_Endian);
  
    result2 = swap_Endians(little_Endian);
  
    System.out.printf("big Endian to little: 0x%x\n" +
                      "litle Endian to big: 0x%x\n",
                       result1, result2);
}
}
  
// This code is contributed by PrinciRaj1992


Python3
# Function to swap a value from
# big Endian to little Endian and
# vice versa.
def swap_Endians(value):
  
    # Get the rightmost 8 bits of the number
    # by anding it 0x000000FF. since the last
    # 8 bits are all ones, the result will be the 
    # rightmost 8 bits of the number. this will
    # be converted into the leftmost 8 bits for the
    # output (swapping)
  
    leftmost_byte = (value & eval('0x000000FF')) >> 0
  
    # Similarly, get the right middle and left  
    # middle 8 bits which will become
    # the left_middle bits in the output
  
    left_middle_byle = (value & eval('0x0000FF00')) >> 8
  
    right_middle_byte = (value & eval('0x00FF0000'))>> 16
  
    # Get the leftmost 8 bits which will be the 
    # rightmost 8 bits of the output
  
    rightmost_byte = (value & eval('0xFF000000'))>> 24
  
    # Left shift the 8 bits by 24
    # so that it is shifted to the 
    # leftmost end
  
    leftmost_byte <<= 24
  
    # Similarly, left shift by 16
    # so that it is in the left_middle
    # position. i.e, it starts at the
    # 9th bit from the left and ends at the
    # 16th bit from the left
  
    left_middle_byle <<= 16
  
    right_middle_byte <<= 8
  
    # The rightmost bit stays as it is
    # as it is in the correct position
  
    rightmost_byte <<= 0
  
    # Result is the concatenation of all these values
  
    result = (leftmost_byte | left_middle_byle 
                  | right_middle_byte | rightmost_byte)
  
  
    return result
  
  
  
# main function
if __name__ == '__main__':
  
    # Consider a hexadecimal value
    # given below. we are gonna convert
    # this from big Endian to little Endian
    # and vice versa.
    big_Endian = eval('0x12345678')
    little_Endian = eval('0x78563412')
      
    result1 = swap_Endians(big_Endian)
  
    result2 = swap_Endians(little_Endian)
  
    print("big Endian to little: % s\nlitle Endian 
              to big: % s" %(hex(result1), hex(result2)))


C#
// C# program to print the difference 
// of Alternate Nodes 
using System;
      
class GFG
{
  
// Function to swap a value from
// big Endian to little Endian and
// vice versa.
static int swap_Endians(int value)
{
  
    // This var holds the leftmost 8
    // bits of the output.
    int leftmost_byte;
  
    // This holds the left middle
    // 8 bits of the output
    int left_middle_byle;
  
    // This holds the right middle
    // 8 bits of the output
    int right_middle_byte;
  
    // This holds the rightmost
    // 8 bits of the output
    int rightmost_byte;
  
    // To store the result
    // after conversion
    int result;
  
    // Get the rightmost 8 bits of the number
    // by anding it 0x000000FF. since the last
    // 8 bits are all ones, the result will be the
    // rightmost 8 bits of the number. this will
    // be converted into the leftmost 8 bits for the
    // output (swapping)
    leftmost_byte = (value & 0x000000FF) >> 0;
  
    // Similarly, get the right middle and left
    // middle 8 bits which will become
    // the left_middle bits in the output
    left_middle_byle = (value & 0x0000FF00) >> 8;
  
    right_middle_byte = (value & 0x00FF0000) >> 16;
  
    // Get the leftmost 8 bits which will be the
    // rightmost 8 bits of the output
    rightmost_byte = (int)(value & 0xFF000000) >> 24;
  
    // Left shift the 8 bits by 24
    // so that it is shifted to the
    // leftmost end
    leftmost_byte <<= 24;
  
    // Similarly, left shift by 16
    // so that it is in the left_middle
    // position. i.e, it starts at the
    // 9th bit from the left and ends at the
    // 16th bit from the left
    left_middle_byle <<= 16;
  
    right_middle_byte <<= 8;
  
    // The rightmost bit stays as it is
    // as it is in the correct position
    rightmost_byte <<= 0;
  
    // Result is the concatenation of all these values.
    result = (leftmost_byte | left_middle_byle | 
              right_middle_byte | rightmost_byte);
  
    return result;
}
  
// Driver Code
public static void Main(String[] args) 
{
    // Consider a hexadecimal value
    // given below. we are gonna convert
    // this from big Endian to little Endian
    // and vice versa.
    int big_Endian = 0x12345678;
    int little_Endian = 0x78563412;
  
    int result1, result2;
  
    result1 = swap_Endians(big_Endian);
  
    result2 = swap_Endians(little_Endian);
  
    Console.Write("big Endian to little: 0x{0:x}\n" +
                    "litle Endian to big: 0x{1:x}\n",
                                   result1, result2);
}
}
  
// This code is contributed by Rajput-Ji


输出:
big Endian to little: 0x78563412
litle Endian to big: 0x12345678