C# 二进制字符串遵守字节顺序

C# binary strings respecting endianess

一直以来,我都需要查看某些数据的 binary/hex 表示形式(tcp 数据包、文件、某些数据结构的二进制序列化,...),而且我似乎总是偶然发现相同的内容每次我编写字符串转换时,字节顺序和字节顺序都会出现问题。

已经有关于这个主题的其他问题,但不知何故我似乎对我的具体实施有一些问题。

我尝试自己编写一些函数来将任何 byte/byte 数组转换为二进制字符串(以 8 个为一组,因为包含的函数仅给出“使用的位”)但问题是我变得不同结果。而且我不知道我在哪里必须关心底层系统的字节顺序。

 class Program
    {
        static void Main(string[] args)
        {
           
            //ushort x = 13;
            ushort x = 3328;
            string res = ToBinaryString(x);
            string res2 = ToBinaryString(BitConverter.GetBytes(x));
            Console.WriteLine("res:  " + res + "\r\n" + "res2: " + res2);
        }

        public static string ToBinaryString(byte v)
        {
            return Convert.ToString(v, 2).PadLeft(8, '0');
        }

        public static string ToBinaryString(byte[] v)
        {
            string[] strArr = new string[v.Length];
            for(int i = 0; i < v.Length; i++)
            {
                strArr[i] = ToBinaryString(v[i]);
            }
            return string.Join("", strArr);
        }

        public static string ToBinaryString(ushort v)
        {
            return Convert.ToString(v, 2).PadLeft(16, '0');
        }
    }
}

意外的不同输出是:

res:  0000110100000000
res2: 0000000000001101

所以我有点困惑,因为到目前为止我认为这两种方法会 return 相同(正确)的结果而不是不同的结果。

值得注意:我在 windows 开发机器上。

好的。

下面的代码与小端机器有关。我没有根据大端来检查它。根据 Microsoft BitConverter.GetBytes 在小端机器上将数字的最低有效字节写入 byteArray 的第一个元素。然后它将下一个更重要的字节写入 byteArray 的第二个元素,依此类推。

由 BitConverter.GetBytes 产生的字节数组元素的顺序取决于机器字节顺序。

这就是您的小端机器中发生的情况。

3328 在十六进制视图中是 D00。 00 是最低有效字节,D 是最高有效字节。 让我们看看将整数传输到 BitConverter.GetBytes(x).

时会发生什么

它将您的数字转换为数组,第一个成员为00,第二个成员为D。 (v[0] = 0; v[1] = D)

让我们来看看

中发生了什么

带字节数组的 ToBinaryString 方法

    string[] strArr = new string[v.Length]

结果是 strArr = 新刺 [2]

然后

    for(int i = 0; i < v.Length; i++)

原来是 for(int i = 0; i < 2; i++)

在第一关,你得到

    strArr[0] = ToBinaryString(v[0]);

=> strArr[0] = "00000000"// 因为你处理的是纯零值。

在第二遍,你得到

    strArr[0] = ToBinaryString(v[1]);

=>

    Convert.ToString(D, 2)

=> 1101

    1101.PadLeft(8, '0')

=>

00001101

现在让我们来看看

    string.Join("", strArr)

就是这样

v[0] + v[1] = "00000000" + "00001101"

即 它 returns 0000000000001101

尝试

    public static string ToBinaryString(byte[] v)
    {
        string[] strArr = new string[v.Length];
        for(int i = v.Length, j = 0; i > 0; i--, j++)
        {
            strArr[i-1] = ToBinaryString(v[j]);
        }
        return string.Join("", strArr);
    }

资源:0000110100000000 res2: 0000110100000000

此致。