Hello everyone. I'm in some serious need of help here.

Several months back I posted a request for assistance in coming up with a 1's-complement checksum generator, given a string of hex data that my application generates. The request was successful and I was able to implement the code with fantastic results. That is, until last week.

There are two parties that need to verify the data that the 2-digit checksum covers. My office, and a remote office. The remote office uses a different software application programmed in C. Thus far there haven't been any issues. Recently however, the other office noted that some of the checksum values were NOT validated by their software.

On our end, the checksum is implemented by the software performing a simple comparison and if the checksum is "valid", a field turns green and the software progresses. If not, an error is flagged. The errors are usually as a result of the user entering erroneous data on our end. We never really look at the checksum value, itself.... we go by the system we have in place with color alerts. Going back and looking at the actual data, I now see that there are a lot of values of "00" as the checksum which our software is flagging as "valid". When the same data set is run through the competing software in the other office, their checksum is coming up as "5F" or "4E", etc. Values that you would expect to see. When I see "00", I think PROBLEM.

So here is the code in question:
Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        strInput = String.Empty
        checksumhexstring = String.Empty
        intSum = 0
        Label1.Text = String.Empty
        Label3.Text = String.Empty
        checksumhexstring = TextBox1.Text
        strInput = checksumhexstring

        'Step 1: Sum all
        'The loop is to 158 because we only consider 80 bytes. Is this always it?
        For i As Integer = 0 To 158 Step 2
            intSum += CInt("&H" & strInput.Substring(i, 2))
        Next

        'Step 2: Rollover
        intSum = intSum \ 256 + (intSum - 256 * (intSum \ 256))

        'Step 3: Find 1's compliment
        intSum = intSum Xor &HFF

        'The following lines check to see the quantity of checksum characters.
        'If there is one character, front-pad with a zero to make two characters.
        'If there are two characters, pass the hex conversion directly.
        'If there are three characters, flag as an error.
        Dim checksumtest As String = String.Empty
        checksumtest = Hex(intSum).ToString.Trim

        If checksumtest.Length = 1 Then
            Label1.Text = "0" & Hex(intSum).ToString
        End If
        If checksumtest.Length = 2 Then
            Label1.Text = Hex(intSum).ToString
        End If
        If checksumtest.Length > 2 Then
            MsgBox("Checksum exceeds two characters")
            Label3.Text = Hex(intSum).ToString
        End If
    End Sub
Now, the variable "checksumhexstring" would contain the following data. I will provide a few sets:

SAMPLE SET
0101513633302D30303033312D303039322D3530585858582D58585800000000000000000000000000000000005430303030 30303030310000000000000000000001010001010E0009AC503603001803

DATA SET 1
0101513930302d30303033302d303039322d3530383133312d30303200000000000000000000000000000000005430303030 3031303036000000000000000000000103050a080e0009ac503600046003

DATA SET 2
0101513930302d30303033302d303039322d3530383133312d30303200000000000000000000000000000000005430303030 3031303035000000000000000000000103050a080e0009ac503600046f03

DATA SET 3
0101513930302d30303033302d303039322d3530383133312d30303200000000000000000000000000000000005430303030 3031303032000000000000000000000103050a080e0009ac503600046603

DATA SET 4
0101513930302d30303033322d303039322d3530383037392d30313500000000000000000000000000000000005430303030 3031303235000000000000000000000103000a100e0009ac503600103e03

DATA SET 5
0101513930302d30303033322d303039322d3530383037392d30313500000000000000000000000000000000005430303030 3031303236000000000000000000000103000a100e0009ac503600104103


When the application is running properly, I see that the checksum for the "Sample Set" is 5A. That is valid and correct.

Data set 1, however, is flagging an error, and the checksum is calculated to be 1FF. That is valid to itself, but is an invalid 2-digit checksum value.

Data set 2 comes up with a F0. That is valid and correct.

Data set 3 is calculated to be 1FD. Again, not a valid value. [As a NOTE, the "valid" checksum the remote office calculated for this set was FC]

Data set 4 is one of those 00 sets. This is not valid. It READS as valid, but in reality it is not valid.

Data set 5 is calculated to be 1FC. Not valid.

I don't know what is going on here. The field lengths have not changed which generates the hex string. Not much of the data within the string changes.... a few bytes here and there. I'm not understanding why these errors are occurring. And especially because it has been working flawlessly since the start - the remote office hasn't had one issue up until recently.

In discussing the issue with the remote office, they suggested that there may be a "folding issue". Now, I'm familiar with the binary process for calculating the 1's-complement, and I'm familiar with folding..... but I am NOT a programming expert and I am not totally clear on how this code works. I received a cursory explanation from the individual who contributed the solution. All I know is it has been working. Could this be a strange math error??

For reference, the remote office has provided JUST the segment of their C code that deals with this checksum:

Code:
/*
 * Function:    card_calc_idprom_checksum
 *
 * Description: This function is used to calculate the 1's complement checksum
 *              of a block of IDPROM data (per RFC 1071, but 8-bit).
 *
 * Parameter:   CARD_IDPROM_SECTION1_FORMAT_T
 *              Pointer to a complete SECTION1 IDPROM data block.
 *
 * Returns:     uint8_t
 *              1's complement checksum of all data bytes in the SECTION1
 *              except the checksum byte its self.
 */
static __inline uint8_t card_calc_idprom_checksum(
    CARD_IDPROM_SECTION1_FORMAT_T * idprom_data)
{
    uint8_t               * data_p;
    int                     index;
    uint32_t                checksum = 0;

    /* We are going to step through the data byte-by-byte */
    data_p = (uint8_t *)idprom_data;

    for (index = 0; index < sizeof(CARD_IDPROM_SECTION1_FORMAT_T) - 1; index++)
{
        checksum += data_p[index];
    }

    /* Fold the carries for the 8-bit checksum */
    while (checksum > 0xFF) {
        checksum = (checksum & 0xFF) + (checksum >> 8);
    }

    return((uint8_t)(~(checksum) & 0xFF));
}
The data they feed into this is identical to the hex strings that I provided above.

I am HOPING that someone who is far more familiar with this material than I am can help me out here. This is above my head and I would appreciate the collective insight of this forum.

THANK YOU VERY MUCH!!

-Dave