C# 二进制字符串尊重字节序

问题描述

一直以来,我都需要查看某些数据的二进制/十六进制表示(tcp 数据包、文件、某些数据结构的二进制序列化...),而且似乎我总是在字节序和字节序方面遇到相同的问题每次写字符串转换时的字节顺序。

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

我尝试为自己编写一些函数来将任何字节/字节数组转换为二进制字符串(以 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

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

值得注意:我使用的是 Windows 开发机器。

解决方法

好的。

下面的代码与一个 little-endian 机器有关。我没有根据 big-endian 来检查它。根据 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

在第一次通过时,你得到

    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"

即 它返回 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

问候。