2012-12-14 145 views
-3

的定製校驗和使用下面的結構:計算一個C#結構

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位結果「?

+7

您好像對Stack Overflow的工作原理有錯誤的想法。您向我們展示您的代碼,解釋您嘗試的方式以及您卡住的位置,然後嘗試提供幫助。你沒有顯示問題的代碼。 – Oded

+0

或者說,@Oded用另一種方式表達:也許你沒有代碼,但你告訴我們你有多遠,你的問題到底是什麼。例如,在添加未簽名的短褲方面你有什麼問題嗎?因爲這是你似乎要求的一部分。 –

+0

感謝您將我置於我的地方Oded。祝你有個美好的一天! – Gerard

回答

2

我首先從結構體(see here)創建一個字節數組,然後使用BitConvert.ToUInt16()來讀取ushort值並從那裏添加。

+0

謝謝喬恩B!這正是我所期待的! – Gerard

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 ; 
    } 
} 

但是,如果有任何填充在結構或在結構的末尾,我不相信你」保證填充八位字節爲零,所以你的結果可能會受到影響。如果你的結構包含奇數個八位字節,你可能會拋出一個異常,試圖讀取結構的結尾......或計算一個不正確的值。

和當然,你可以序列的結構來存儲數據流,然後讀取作爲ushorts流:

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 ; 
    } 
} 

但是關於佈局和字節順序和填充同樣的,這使得假設。如果結構尺寸很奇怪,你幾乎肯定會拋出異常。

+0

謝謝尼古拉斯。這很好! – Gerard