关于CheckSum

//Checksum.h

class checksum {
public:
    checksum() { clear(); }
    void clear() { sum = 0; r = 55665; c1 = 52845; c2 = 22719;}
    void add(DWORD w);
    void add(BOOL w) { add((DWORD)w); }
    void add(UINT w) { add((DWORD)w); }
    void add(WORD w);
    void add(const CString & s);
    void add(LPBYTE b, UINT length);
    void add(BYTE b);
    DWORD get() { return sum; }
protected:
    WORD r;
    WORD c1;
    WORD c2;
    DWORD sum;
};

Don't worry about those "magic constants" you see r, c1, and c2 being initialized to. They are part of the encryption algorithm, and although I'm sure there is some mystical reason they are set to the particular values shown, many other values (perhaps any other values, except possibly 0 or 1) would suffice.

Note the use of overloading to get various data types. To use the checksum algorithm, create a variable of type checksum, for example, in your desired data structure. You can then call the various add methods to add in the values you wish to checksum (it is rarely the case that doing a checksum of the bytes of the structure yields anything useful; for example, some might represent transient computations that do not affect the actual values of importance; and checksumming the bytes would mean that you checksum the pointers to strings, not the contents of the strings, which leads to the situation where two strings that are otherwise identical would produce different checksums because they were at different addresses. So at some point you determine the structure contains all the values you care about (for example, just after you've read the document, or initialized all the values in OnInitDialog), and you apply the following operations to your checksum variable (which I'll call original). It is convenient to package up the checksum algorithm as shown.

void CMyClass::doChecksum(checksum & chk)
   {
    chk.clear();
    chk.add(flag); // a BOOL
    chk.add(text); // a CString
    chk.add(size); // a DWORD
   }

so you call it as

    doChecksum(original);Now, at some point, you determine that you have changed something; for example, the user has clicked a checkbox. You capture the Boolean value of the checkbox to the flag variable, then call doChecksum with a new variable, for example, by having the button-clicked, edit-changed, etc. handler call a function computeModification

void CMyClass::computeModification()
   {
    checksum current;
    current.clear();
    doChecksum(current);
    CMyClass::SetModified(current.get() != original.get());
   }

Note that if the checkbox was originally unchecked, and the user checks it, we get an indication (at least in the Modified flag) that the document has changed. If the user then unchecks it, and all other values have been unchanged, we get an indication that the content has not been modified (this means the checksum has to account for all forms of change! And that's your responsibility!)

Checksum.cpp
#include "stdafx.h"

#include "Checksum.h"

/****************************************************************************
*                                  checksum::add
* Inputs:
*        DWORD d: word to add
* Result: void
*
* Effect:
*        Adds the bytes of the DWORD to the checksum
****************************************************************************/

void checksum::add(DWORD value)
{
 union { DWORD value; BYTE bytes[4]; } data;
 data.value = value;
 for(UINT i = 0; i < sizeof(data.bytes); i++)
    add(data.bytes[i]);
} // checksum::add(DWORD)

/****************************************************************************
*                                 checksum::add
* Inputs:
*        WORD value:
* Result: void
*
* Effect:
*        Adds the bytes of the WORD value to the checksum
****************************************************************************/

void checksum::add(WORD value)
{
 union { DWORD value; BYTE bytes[2]; } data;
 data.value = value;
 for(UINT i = 0; i < sizeof(data.bytes); i++)
   add(data.bytes[i]);
} // checksum::add(WORD)

/****************************************************************************
*                                 checksum::add
* Inputs:
*        BYTE value:
* Result: void
*
* Effect:
*        Adds the byte to the checksum
****************************************************************************/

void checksum::add(BYTE value)
{
 BYTE cipher = (value ^ (r >> 8));
 r = (cipher + r) * c1 + c2;
 sum += cipher;
} // checksum::add(BYTE)
/****************************************************************************
*                                 checksum::add
* Inputs:
*        const CString & s: String to add
* Result: void
*
* Effect:
*        Adds each character of the string to the checksum
****************************************************************************/

void checksum::add(const CString & s)
{
 for(int i = 0; i < s.GetLength(); i++)
    add((BYTE)s.GetAt(i));
} // checksum::add(CString)

/****************************************************************************
*                                 checksum::add
* Inputs:
*        LPBYTE b: pointer to byte array
*        UINT length: count
* Result: void
*
* Effect:
*        Adds the bytes to the checksum
****************************************************************************/

void checksum::add(LPBYTE b, UINT length)
{
for(UINT i = 0; i < length; i++)
   add(b[i]);
} // checksum::add(LPBYTE, UINT)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值