B4R Question XOR array elements

Mostez

Well-Known Member
Licensed User
Longtime User
I receive hex string from RFID module RDM6300 representing card data, I want to calculate the checksum as shown in attached file and compare it with the checksum sent from the card,
this event is raised when hex string is received, the Buffer array holds 14 bytes:
B4X:
private Sub ReadRFID(Buffer() As Byte)
Log(Buffer)
these are two card data as logged by B4R (ASCII start and end characters are not displayed here)

000029CE688F , checksum 8F
00004A9939EA, checksum EA

The Buffer array elements 1 to 10 should be XORed to produce the checksum, any ideas how to do that?
TIA
 

Attachments

  • RDM6300.jpg
    RDM6300.jpg
    43.9 KB · Views: 39

hatzisn

Well-Known Member
Licensed User
Longtime User
I receive hex string from RFID module RDM6300 representing card data, I want to calculate the checksum as shown in attached file and compare it with the checksum sent from the card,
this event is raised when hex string is received, the Buffer array holds 14 bytes:
B4X:
private Sub ReadRFID(Buffer() As Byte)
Log(Buffer)
these are two card data as logged by B4R (ASCII start and end characters are not displayed here)

000029CE688F , checksum 8F
00004A9939EA, checksum EA

The Buffer array elements 1 to 10 should be XORed to produce the checksum, any ideas how to do that?
TIA

use byte converter's hex to bytes function and then the bit.xor function.
 
Upvote 0

hatzisn

Well-Known Member
Licensed User
Longtime User
use byte converter's hex to bytes function and then the bit.xor function.

If the buffer is per character then use first:

B4X:
Dim bc As ByteConverter
Dim sHex As String = bc.StringFromBytes(Buffer)

And then XOR until the byte before last using previous post.
 
Upvote 0

Mostez

Well-Known Member
Licensed User
Longtime User
use byte converter's hex to bytes function and then the bit.xor function.
that's not the problem, I'm confused about how to get the hex-represented bytes in pairs and then XOR them one after another in For Next loop
 
Upvote 0

emexes

Expert
Licensed User
how to get the hex-represented bytes in pairs
hex string is received, the Buffer array holds 14 bytes

Righto, so far, so good. XORing those 7 sets of 2 hex digit bytes would be no problem.

But "ASCII start and end characters are not displayed here" leads to some ambiguities.

Are the start and end characters (2 x 2 hex digit bytes?) to be included in the checksum?

B4X:
private Sub ReadRFID(Buffer() As Byte)
Log(Buffer)

What is the exact output of the Log(Buffer) call? ie all 14 ASCII hex digits?

Does that output include the checksum generated by the sender?

If so, then underlining that checksum would be useful.

Bolding the "ASCII start and end characters" would be useful too.

Also, are the received packets always the same length, or are the first two and last four hex digits to be skipped?
 
Upvote 0

emexes

Expert
Licensed User
no, just the ten bytes following the start char in buffer

Well, making guesses in the absence of the other information, and with me banging up demo code in B4J because I don't have B4R...

then this packet handler:
B4X:
Sub HandlePacket(Buffer() As Byte)
    Dim bc As ByteConverter
    
    Dim BufferString As String = bc.StringFromBytes(Buffer, "ISO-8859-1")
    Log("BufferString = " & BufferString)
    
    'chop off first and last characters (StartOfPacket and EndOfPacket)
    Dim HexString = BufferString.SubString2(1, BufferString.Length - 1)
    Log("HexString = " & HexString)
    
    'convert each 2 hex digits to 1 byte
    Dim HexBytes() As Byte = bc.HexToBytes(HexString)

    For I = 0 To HexBytes.Length - 1
        Log(I & TAB & ByteToUnsigned(HexBytes(I)) & TAB & ByteToHex(HexBytes(I)))
    Next
    
    Dim CheckValue As Byte = 0
    For I = 0 To HexBytes.Length - 2    'not including last byte (received checkvalue?)
        CheckValue = Bit.Xor(CheckValue, HexBytes(I))
    Next

    Dim ReceivedCheckValue As Byte = HexBytes(HexBytes.Length - 1)
    
    Log("Calculated checkvalue = " & ByteToHex(CheckValue))
    Log("Received checkvalue = " & ByteToHex(ReceivedCheckValue))
End Sub
supported by these helper routines:
1,8:
Sub ByteToHex(B As Byte) As String
    Dim bc As ByteConverter
    Dim OneByte(1) As Byte
    OneByte(0) = B
    Return bc.HexFromBytes(OneByte)
End Sub

Sub ByteToUnsigned(B As Byte) As Int
    Return Bit.And(B, 0xFF)
End Sub
and tested using:
B4X:
Dim bc As ByteConverter

Dim StartOfPacket As String = ":"
Dim EndOfPacket As String = "$"
Dim SamplePacket As String = StartOfPacket & "000029CE688F" & EndOfPacket

Dim Buffer() As Byte = bc.StringToBytes(SamplePacket, "ISO-8859-1")

For I = 0 To Buffer.Length - 1
    Log(I & TAB & Buffer(I) & TAB & Chr(Buffer(I)))
Next

HandlePacket(Buffer)
produces the promising-looking:
Log output:
0    58    :
1    48    0
2    48    0
3    48    0
4    48    0
5    50    2
6    57    9
7    67    C
8    69    E
9    54    6
10    56    8
11    56    8
12    70    F
13    36    $
BufferString = :000029CE688F$
HexString = 000029CE688F
0    0    00
1    0    00
2    41    29
3    206    CE
4    104    68
5    143    8F
Calculated checkvalue = 8F
Received checkvalue = 8F
 
Upvote 0

emexes

Expert
Licensed User
A neat trick with the XOR checkvalue here is that, if you XOR the data and the checkvalue all together, then the result is zero.

(if the checkvalue is correct :rolleyes: otherwise non-zero)

But I agree it's nicer during debugging to see the calculated checkvalue separately. 🍻
 
Upvote 0

Mostez

Well-Known Member
Licensed User
Longtime User
I'd like to thank you all for your great help, here is my final code:
B4X:
'    card data examples:
'    (CHR2)000029CE688F(CHR3) -- checksum 8F
'    (CHR2)00004A9939EA(CHR3) -- checksum EA >> 00-00-4A-99-39 should be XORed to produce checksum

tmpCheckSum = BC.SubString2(Buffer,11,13) 'get card saved checksum i.e EA like example above
Str_HexNumber = BC.StringFromBytes(tmpCheckSum)
cardCheckSum = Bit.ParseInt(Str_HexNumber, 16)
tmpData = BC.SubString2(Buffer,1,11) 'get card data array i.e 00-00-4A-99-39 like example above

If tmpData.Length <> RDM6300_DATA_SIZE Then Return 0
'loop and xor all elements in pair
For x = 0 To tmpData.Length -1 Step 2
    Dim tmpD (2) As Byte
    Dim tmpB As UInt
    tmpD = BC.SubString2(tmpData,X,X+2)
    Str_HexNumber = BC.StringFromBytes(tmpD)
    tmpB = Bit.ParseInt(Str_HexNumber, 16)
    calcCheckSum = Bit.Xor(calcCheckSum,tmpB)
Next
    
'compare calculated checksum with card checksum
If cardCheckSum <> calcCheckSum Then Return 0
 
Upvote 0

Similar Threads

Top