The code below incorporates Steve's suggestion and additional changes.
Firstly, since
sentence is passed by reference in your code that precludes calling the function with a constant string parameter. That may or may not be an important limitation.
Secondly, the upper limit of the For loop was computed as the length of the trimmed input string but the bytes being added to the checksum were being retrieved from the untrimmed input string. This would only be important if the input string had leading space characters.
Thirdly, the optional second parameter to the Asc() function can be used to eliminate the need to generate intermediate 1-byte strings.
Another issue that is not addressed is the assumption that the input string has the correct format. If the caller checks the format before calling this function then that is not an issue.
Code: Select all
Function NMEA_Checksum(ByVal sentence as String) As String
Dim s as String
Dim i as Integer
Dim sum as Byte
s = Trim(sentence)
sum=0
For i = 2 To Len(s) - 2
sum = sum Xor Asc(s, i)
Next i
NMEA_Checksum = CStrHex(sum)
End Function
As a side note, one characteristic of the Xor function is that performing the operation a second time with the same value reverses the effect of the initial operation, i.e. A Xor B Xor A equals B. The operation is commutative so the order of operations is unimportant. The upshot of this is that you needn't skip the first and last characters if you initialize the checksum to the Xor of those two characters. The inner code block would then be:
Code: Select all
sum = Asc("$") Xor Asc("*") ' negate the effect of the first and last characters
For i = 1 To Len(s)
sum = sum Xor Asc(s, i)
Next i