Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
Solved

# ASCII and HEX algorithms

Posted on 2005-05-14
Medium Priority
1,450 Views
Hi All,

I am tinkering with some software for a computer interface. Anyway, it uses a message of the following format and I need some help with writing a procedure to calculate the checksum and send the data through the serial port.

Here is the information:

Format is: [IDENT][SIZE][PARAMS][CHECKSUM]<CR>

IDENT is the message id (single ascii character)
SIZE is the 8-bit number in ascii-hex (2 chrs)
PARAMS optional field...
CHECKSUM is 8-bit sum of fields IDENT, SIZE and PARAMS in ascii-hex (2 chrs)
<CR> terminator in ascii (0Dh)

example message is: d0601234507

d = ident
06 = size
012345 = data in params
07 = checksum

actual data being tx is (hex): 64 30 36 30 31 32 33 34 35 30 37

This is the confusing (to me at least) bit:

1. take the modulo-2 sum of all message bytes preceding checksum
2. retain bits 0...7, discarding any higher order bits resulting from the summation
3. form the "two's compliment" of the remainder
4. convert the binary number into 2 ascii hex digits, msd first

using eg above: d0601234507

take sum of all msg bytes and retain only bits 0...7
hex addition = 64h + 30h + 36h + 30h + 31h + 32h + 33h + 34h + 35h = F9h
take the's compliment of F9h = 07H

-------------------------------

Can someone assist??

0
Question by:nzfire
• 10
• 7

LVL 37

Expert Comment

ID: 14005627
What help do you need?

64h + 30h + 36h + 30h + 31h + 32h + 33h + 34h + 35h = F9h

In Hex, A = 10, B = 11, C = 12, D = 13, E = 14, F = 15 and the base is 16

4 + 0 + 6 + 0 + 1 + 2 + 3 + 4 + 5 =  25

If you are adding in Decimal, Int(25/10) =  2 will be carry and remainder 5 will be the sum at the unit place.
But in hex, Int(25/16) = 1 is the carry and remainder 9 is the unit digit.

Now,
6 + 3 + 3 + 3 + 3 + 3 + 3 + 3 + 3 = 30 + 1 carry = 31
So, Int(31/16) = 1 is the carry and remainder = 15 = F is the digit at 10's place (16's place to be precise)

6   4
3   0
3   6
3   0
3   1
3   2
3   3
3   4
3   5
______________
1   F   9

Ignore carry you will get F9

Now to get complement, subtract each digit by 16-1=15
15 - F = 15 - 15 = 0
15 - 9 = 6
You will get 06
This is 15's complement (255's complement of number)

To get 16's complement, add 1 to it

06 + 01 = 07

This is the result you need
0

LVL 37

Expert Comment

ID: 14005642
Not sure if that is what you needed...

0

LVL 1

Author Comment

ID: 14005658
mgh_mgharish this is excellent.

I need to write a vb function that will generate the so called CHECKSUM given a message.

Going back to my example of: d0601234507

d = ident
06 = size
012345 = data in params
07 = checksum

I need to be able to pass (in this instance d06012345) to the function and for it to return the CHECKSUM. Sorry, maths was never my favourite subject!! haha

Heres where I would like some help:

1) My 'message' string will vary in length and I would like to understand how to Take the modulo-2 sum of all message bytes preceding the Checksum (in this case 07) and retain bits 0...7, discarding any higher order bits resulting from the summation.

2) From there I need to form the twoâ€™s complement of the remainder and convert the binary number into two ASCII-hex digits, MSD first.

What you have seems to work perfectly, and If I can get it into a vb function that would be the answer to my problems.

0

LVL 37

Expert Comment

ID: 14005671
My 'message' string will vary in length and I would like to understand how to Take the modulo-2 sum of all message bytes preceding the Checksum (in this case 07) and retain bits 0...7, discarding any higher order bits resulting from the summation.

I don't understand.. can you elaborate please ?

What does your 'message' string contain ? -- d0601234507
Take the modulo-2 sum of all message bytes preceding the Checksum (in this case 07)

0 1 2 3 4 ? = A
or
d 0 6 1 2 3 4 5 ? = 1D

0

LVL 37

Expert Comment

ID: 14005675
0 1 2 3 4 5 ? = F
or
d 0 6 1 2 3 4 5 ? = 1D
0

LVL 37

Expert Comment

ID: 14005684
Or.. are you getting 64 30 ..... after d061234507 ?
0

LVL 1

Author Comment

ID: 14005686
Sorry, I should have made that a bit clearer:

I need to add the hex values of the message string

d06012345 =  : 64h + 30h + 36h + 30h + 31h + 32h + 33h + 34h + 35h = F9h

here is the start of my code:

'Begin-------

Public Sub GetChecksum(ByVal sMessage As String)

Dim iChecksum As Integer
iChecksum = 0
Dim iCharacter As String

Dim i As Integer
For i = 1 To Len(sMessage)
iCharacter = Mid(sMessage, i, 1)

If iChecksum = 0 Then
' Yes. Set the checksum to the value
iChecksum = Hex(Asc(iCharacter))
Else
iChecksum = iChecksum + Hex(Asc(iCharacter))
End If

Next

End Sub

'End----------
0

LVL 37

Expert Comment

ID: 14005691
Ah.. now I understand.. you are taking the ascii values of d 0 6 ... and then adding... right?
0

LVL 1

Author Comment

ID: 14005696
yes, I am
0

LVL 1

Author Comment

ID: 14005703
Heres another example I found: (if it helps)

Example
#12C401060A010000BASE8F             (message)
1. Take the modulo-2 sum of all message bytes preceding [CHECKSUM]. (checksum is the last two ascii digits)
â€¢ # = 23h, 1 = 31h, 2 = 32h, C = 43h etc. therefore the modulo-2 sum is:
23h + 31h + 32h + 43h + 34h + 30h + 31h + 30h + 36h + 30h + 41h + 30h + 31h + 30h
+30h + 30h + 30h + 42h + 41h + 53h + 45h = 471h
2. Retain bits 0 to 7, discarding any higher order bits resulting from the summation.
â€¢ 71h
3. Form the twoâ€™s complement of the remainder.
â€¢ 71h = 0111 0001
twoâ€™s complement = 1000 1111
4. Convert the binary number into two ASCII-hex digits, MSD first.
â€¢ 1000 1111 = 8F
0

LVL 37

Accepted Solution

Harisha M G earned 2000 total points
ID: 14005723
Well... here is a simple function... in VB

Public Function GetCheckSum(ByVal sMessage As String) As String
Dim CheckSum As Long
For i = 1 To Len(sMessage)
CheckSum = CheckSum + Asc(Mid(sMessage, i, 1))
Next
CheckSum = 256 - CheckSum Mod 256
GetCheckSum = Hex(CheckSum)
If (Len(GetCheckSum) = 1) Then GetCheckSum = "0" & GetCheckSum
End Function

This will return a string which will be the CheckSum
0

LVL 1

Author Comment

ID: 14005738
I was starting to understand your first post. I rand that code with "d0612345" being the message an the return was 37 not 07 in hex...as it should be..

<confusion looms>
0

LVL 37

Expert Comment

ID: 14005750
Where is 0 in your message ?
d0612345

It should have been

d06012345

Right ?
0

LVL 1

Author Comment

ID: 14005764
Oops...typo!
Thats great! Thanks so much for your help. If I have any other questions, I will be calling upon you for your services again!

0

LVL 37

Expert Comment

ID: 14005807
Thanks
0

LVL 1

Author Comment

ID: 14026141
mgh_mgharish,

I have a problem with this code. Don't know if you'll se an email alert re: this question, but I am reposting it. The checksum works for some messages, but not others.

code to follow:

'begin:

Public Function GetCheckSum(ByVal sMessage As String, Optional ByVal bIncludeMessage As Boolean) As String
'//Check that there is something in the sMessage
If sMessage = vbNullString Then
Exit Function
End If

Dim CheckSum As Long
Dim i As Integer

For i = 1 To Len(sMessage)
CheckSum = CheckSum + Asc(Mid(sMessage, i, 1))
Next

CheckSum = 256 - CheckSum Mod 256
GetCheckSum = Hex(CheckSum)

If (Len(GetCheckSum) = 1) Then
GetCheckSum = "0" & GetCheckSum
End If

If bIncludeMessage = True Then
GetCheckSum = sMessage & GetCheckSum
End If

End Function

'here are some samples (note the differences eg ..D27F.. and ..D24..
'Checksum for d0E0D27F1CCC1D00D = F1 (works)
'Checksum for d0E0D27F1CCC1500D = 100 (fails - can only be a 2 digit hex)
'Checksum for d0E0D5241CCC1500D = 14 (works)
'Checksum for d0E0D5241CCC1D00D = 05 (works)

quick rundown on the message:
d = prefix
characters 2 & 3 are hex length of D27F1CCC1D00D = 13 (no worried, it will always be 13 for now)
rest is message...ie D27F1CCC1D00D

I believe that the checksum generated is correct as far as adding it up, but I think there is something wrong as it should only be two, and maybe its happening (refer original question) when I am supposed to get the "two's complement" of it...

Your code works fine, its just certain strings that seem to shake it up a little.

If you are able to help, i'd greatly appreciate it, and you'll get max points.

Cheers,

Sean
0

LVL 37

Expert Comment

ID: 14038725
OK.. a small change will do the job...

CheckSum = 256 - CheckSum Mod 256
CheckSum = CheckSum Mod 256                   '<------------- Add this line
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate rowâ€¦
Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no oâ€¦
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that aâ€¦
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This lâ€¦
###### Suggested Courses
Course of the Month11 days, 4 hours left to enroll