-4

使用以下结构:

public struct ION
{
    public Single a0;
    public Single a1;
    public Single a2;
    public Single a3;
    public Single b0;
    public Single b1;
    public Single b2;
    public Single b3;
    public Double A1;
    public Double A0;
    public UInt32 Tot;
    public Int16 Wnt;
    public Int16 DtLS;
    public Int16 WnLSF;
    public Int16 DN;
    public Int16 DtLSF;
    public Int16 Wn;
    public UInt32 Tow;
    public Int16 bulwn;
    public UInt32 bultow;
    public UInt16 checksum;
}

...如果校验和值“通过将结构分解为 37 个无符号短裤,将它们相加并取结果的最低有效 16 位来计算”,我将如何计算校验和值?

4

2 回答 2

2

我将首先从结构创建一个字节数组(参见此处),然后使用BitConvert.ToUInt16()读取ushort值并从那里添加。

于 2012-12-14T19:55:08.560 回答
1

这是一种方法,但这是否符合要求……谁知道呢。cpu字节序重要吗?

public struct ION
{
    public Single a0    ;
    public Single a1    ;
    public Single a2    ;
    public Single a3    ;
    public Single b0    ;
    public Single b1    ;
    public Single b2    ;
    public Single b3    ;
    public Double A1    ;
    public Double A0    ;
    public UInt32 Tot   ;
    public Int16  Wnt   ;
    public Int16  DtLS  ;
    public Int16  WnLSF ;
    public Int16  DN    ;
    public Int16  DtLSF ;
    public Int16  Wn    ;
    public UInt32 Tow   ;
    public Int16  bulwn ;
    public UInt32 bultow ;

    public UInt16 checksum
    {
        get
        {
            byte[][] raw =
            {
                BitConverter.GetBytes( a0     ) ,
                BitConverter.GetBytes( a1     ) ,
                BitConverter.GetBytes( a2     ) ,
                BitConverter.GetBytes( a3     ) ,
                BitConverter.GetBytes( b0     ) ,
                BitConverter.GetBytes( b1     ) ,
                BitConverter.GetBytes( b2     ) ,
                BitConverter.GetBytes( b3     ) ,
                BitConverter.GetBytes( A1     ) ,
                BitConverter.GetBytes( A0     ) ,
                BitConverter.GetBytes( Tot    ) ,
                BitConverter.GetBytes( Wnt    ) ,
                BitConverter.GetBytes( DtLS   ) ,
                BitConverter.GetBytes( WnLSF  ) ,
                BitConverter.GetBytes( DN     ) ,
                BitConverter.GetBytes( DtLSF  ) ,
                BitConverter.GetBytes( Wn     ) ,
                BitConverter.GetBytes( Tow    ) ,
                BitConverter.GetBytes( bulwn  ) ,
                BitConverter.GetBytes( bultow ) ,
            } ;
            byte[] cooked = raw.SelectMany( x => x ).ToArray() ;
            uint  accumulator = 0 ;

            for ( int i = 0 ; i < cooked.Length ; i+= 2 )
            {
                ushort value = BitConverter.ToUInt16( cooked , i ) ;
                accumulator += value ;
            }
            return (ushort) accumulator ;
        }
    }

}

或者您可以下拉到不安全的代码并执行以下操作:

public UInt16 checksum
{
  get
  {
    uint accumulator = 0 ;
    unsafe
    {
      fixed ( ION* x = &this )
      {
        for ( ushort *p = (ushort*) x ; p < x+1 ; ++p )
        {
          accumulator += *p ;
        }
      }
    }
    return (ushort) accumulator ;
  }
}

但是,如果结构中或结构末尾有任何填充,我不相信您可以保证填充八位字节为零,因此您的结果可能会受到影响。如果你的结构包含奇数个八位字节,你可能会抛出一个异常,试图读取结构的末尾......或计算一个不正确的值。

当然,您可以将结构序列化为内存流,然后将其作为 ushort 流读取:

public UInt16 checksum
{
  get
  {
    uint accumulator = 0 ;
    using ( BinaryReader reader = new BinaryReader( new MemoryStream() ) )
    {
      BinaryFormatter bf = new BinaryFormatter();
      bf.Serialize( reader.BaseStream , this ) ;
      reader.BaseStream.Seek(0,SeekOrigin.Begin) ;
      while ( reader.BaseStream.Position < reader.BaseStream.Length )
      {
        ushort value = reader.ReadUInt16() ;
        accumulator += value ;
      }
    }
    return (ushort) accumulator ;
  }
}

但同样,这是对布局、字节顺序和填充的假设。如果结构大小是奇数,你几乎肯定会抛出异常。

于 2012-12-14T21:16:27.297 回答