【问题标题】:C#, BitConverter.ToUInt32, incorrect valueC#,BitConverter.ToUInt32,不正确的值
【发布时间】:2014-01-02 21:19:33
【问题描述】:

我尝试将 IP 地址转换为长值:

byte[] Ip = new byte[4] { 192, 168, 1, 0 };

UInt32 Ret1 = (((UInt32)Ip[0]) << 24) |
              (((UInt32)Ip[1]) << 16) |
              (((UInt32)Ip[2]) << 8)  |
              (((UInt32)Ip[3]));

UInt32 Ret2 = BitConverter.ToUInt32(Ip, 0);

Ret1 返回3232235776(正确值)

Ret2 返回108736 (?)

为什么会有这种差异?

【问题讨论】:

  • Ret1 returns 3232235776 (the correct value)?根据哪个字节序?使用更多相关的API怎么样new IPAddress(new byte[] { 192, 168, 1, 0 })

标签: c# bitconverter


【解决方案1】:

确实,字节顺序是您的问题。虽然不难解决,但在基于 Intel 的系统上有时会很烦人,因为它们处于 Little EndianNetwork OrderBig Endian强>。简而言之,您的字节顺序相反。

这里有一些方便的方法可以用来解决这个问题(甚至在各种平台上):

static uint MakeIPAddressInt32(byte[] array)
{
  // Make a defensive copy.
  var ipBytes = new byte[array.Length];
  array.CopyTo(ipBytes, 0);

  // Reverse if we are on a little endian architecture.
  if(BitConverter.IsLittleEndian)
    Array.Reverse(ipBytes);

  // Convert these bytes to an unsigned 32-bit integer (IPv4 address).
  return BitConverter.ToUInt32(ipBytes, 0);
} 

【讨论】:

  • 感谢 Array.Reverse 是解决方案!
【解决方案2】:

听起来你的字节序有问题。

http://en.wikipedia.org/wiki/Endianness

【讨论】:

    【解决方案3】:

    平台(位数)独立代码可以这样看:

    UInt32 Ret2 = BitConverter.ToUInt32(
                       BitConverter.IsLittleEndian
                       ? Ip.Reverse().ToArray()
                       : Ip, 0);
    

    【讨论】:

      【解决方案4】:

      这是一个字节序问题。 IPAddress.HostToNetworkOrder 具有各种重载,用于将数字类型转换为其网络等效项(即小端到大端)。

      【讨论】:

        【解决方案5】:

        IP 地址通常以 网络字节顺序 编写,这恰好是标准 x86 的另一种字节序。

        Google 搜索 aton()ntoa()big endian

        【讨论】:

        • 网络顺序是大端。 x86 架构是小端的。
        • 正如我的回答所说:网络字节顺序是标准 y86 的另一种字节序。
        猜你喜欢
        • 1970-01-01
        • 2013-01-12
        • 2020-04-17
        • 2018-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-02
        相关资源
        最近更新 更多