[英]How to calculate the checksum of the structure having different datatypes?
我需要用這個 header 填充二進制文件。header 的校驗和將添加到 header 的末尾。校驗和應為 1 字節總和
typedef struct {
uint32 startAddress;
uint16 size;
uint32 EndAddress;
uint8 type;
uint8 version;
uint16 modelNo;
uint8 checksum;
uint8 reserved[32];
}
結構包含不同數據類型的事實並不是真正的問題 - 您可以將需要校驗和的 object 的地址轉換為uint8*
並將其視為字節數組。
您真正的問題是編譯器可以自由地以實現定義的方式對齊成員並在成員之間插入填充以強制 alignment。填充字節的值是不確定的但校驗和將包括它們,使它們不可比較實例之間。
簡單的解決方案是覆蓋自然 alignment 並通過編譯器提供的任何方式“打包”結構。 這對資源嚴重受限的系統有好處,但並不總是合適的。 您可能會考慮序列化 function,其中成員被單獨復制到一個字節數組,然后您對其進行校驗和。 然而,與編譯器打包相比,序列化是資源和處理器密集型的,並且可能容易出錯和維護開銷。
打包和序列化的替代方法可能是使用memset()
為每個這樣的 object 初始化整個結構空間,以便填充將具有已知的零值,但是如果您有多個這樣的對象,這也很難維護和執行.
因此,總的來說,您決定以任何方式打包此結構(編譯器以各種方式支持__attribute__ or
#pragma` 甚至全局編譯器選項。然后您可能會重新考慮您的結構設計以將 header 從校驗和和有效負載中拆分出來:
typedef struct
{
uint32 startAddress;
uint16 size;
uint32 EndAddress;
uint8 type;
uint8 version;
uint16 modelNo;
} __attribute__((__packed__)) sHeader ;
typedef struct
{
sHeader header ;
uint8 checksum;
uint8 reserved[32];
} __attribute__((__packed__)) sInfo ;
然后給出:
sInfo some_info = ... ;
然后:
info.checksum = 0 ;
for( int i = 0; i < sizeof(some_info .header); i++ )
{
info.checksum += ((uint8*)(&some_info.header))[i] ;
}
如果您選擇堅持使用現有結構,那么它會稍微復雜一些:
typedef struct
{
uint32 startAddress;
uint16 size;
uint32 EndAddress;
uint8 type;
uint8 version;
uint16 modelNo;
uint8 checksum;
uint8 reserved[32];
} __attribute__((__packed__)) sInfo ;
sInfo some_info = ... ;
然后:
ptrdiff_t header_length = (uint8*)(&some_info.checksum) - (uint8*)(&some_info) ;
info.checksum = 0 ;
for( int i = 0; i < header_length; i++ )
{
info.checksum += ((uint8*)(&some_info.header))[i] ;
}
第二種方法更復雜且容易出錯,它使用運行時計算 header 大小而不是第一種方法的編譯時sizeof()
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.