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: 502
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
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
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
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?

Code:
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
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:
[CODE lang="b4x" highlight="18-21"]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
[/CODE]
supported by these helper routines:
[CODE lang="b4x" title="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[/CODE]
and tested using:
[CODE lang="b4x" highlight="5,13"]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)[/CODE]
produces the promising-looking:
[CODE lang="html" title="Log output" highlight="15,23"]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[/CODE]
 
Upvote 0
me banging up demo code in B4J because I don't have B4R

If B4R chokes on the Strings then let me know and I will rewrite it to just use Bytes.

Speaking of which: are B4R Bytes signed (-128 to 127) or unsigned (0 to 255)?
 
Upvote 0
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
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
Back
Top