Arduino RFID checksum calculation and key visualization

前端 未结 2 1285
日久生厌
日久生厌 2021-01-21 17:05

I\'m using this RFID module for Arduino Ethernet R3 and I need to retrieve from the Software Serial the card (TAG) ID that is written outside the tag. The module\'s datasheet sa

相关标签:
2条回答
  • 2021-01-21 17:11

    Here's a walkthrough of how to calculate the checksum.

    Take your card number (this is just directly quoted from your text)

    I received: 2
    I received: 51
    I received: 67
    I received: 48
    I received: 48
    I received: 67
    I received: 69
    I received: 55
    I received: 53
    I received: 52
    I received: 67
    I received: 67
    I received: 66
    I received: 3
    

    This would give you a number that is equivalent to the following:

    2 51 67 48 48 67 69 55 53 52 67 67 66 3

    The first numer (2) indicates that this is the beginning of a request.

    The last number (3) indicates that this is the end of a request.

    2 51 67 48 48 67 69 55 53 52 67 67 66 3

    For the purposes of calculating the checksum, we are going to remove these two numbers. So your new number is now:

    51 67 48 48 67 69 55 53 52 67 67 66

    The last two numbers that you have are your checksum. The remaining numbers are your card number. So:

    Your card number is:

    51 67 48 48 67 69 55 53 52 67

    And your checksum is:

    67 66

    Next you need to convert your Card Number and your Checksum to ASCII values:

    Your card number is:

    3 C 0 0 C E 7 5 4 C

    And your checksum is:

    C B

    Next, grab each number into pairs:

    Your card number is:

    3C 00 CE 75 4C

    And your checksum is:

    CB

    Then you need to treat each pair as a HEXIDECIMAL value and do an XOR against them. So basically you need to prove the following:

    3C ^ 00 ^ CE ^ 75 ^ 4C == CB

    (3C ^ 00) = 3C

    3C ^ CE ^ 75 ^ 4C == CB

    (3C ^ CE) = F2

    F2 ^ 75 ^ 4C == CB

    (3C ^ CE) = 87

    87 ^ 4C == CB

    (87 ^ 4C) = CB

    CB == CB

    Because CB == CB, this is a valid transaction.

    No doubt someone else can come up with a better approach than this, but there should be enough pseudo code here for you to write it yourself.

    0 讨论(0)
  • 2021-01-21 17:16

    I found this blog which has an implementation in Arduino, I've adapted it to work in Java and results are good. Since there are a lot of bitwise operations - I used http://www.miniwebtool.com/bitwise-calculator/ to try to understand what's going on. I understand all of it except (val | (tempbyte << 4)), I mean I understand what the statement does, I just struggle to see how that produces the result I want.

    void loop () {
      byte i = 0;
      byte val = 0;
      byte code[6];
      byte checksum = 0;
      byte bytesread = 0;
      byte tempbyte = 0;
    
      if(Serial.available() > 0) {
        if((val = Serial.read()) == 2) {
          // check for header 
          bytesread = 0; 
          while (bytesread < 12) {
            // read 10 digit code + 2 digit checksum
            if( Serial.available() > 0) {
              val = Serial.read();
              if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) {
                // if header or stop bytes before the 10 digit reading
                break;
                // stop reading
              }
              // Do Ascii/Hex conversion:
              if ((val >= '0') && (val <= '9')) {
                val = val - '0';
              } else if ((val >= 'A') && (val <= 'F')) {
                val = 10 + val - 'A';
              }
              // Every two hex-digits, add byte to code:
              if (bytesread & 1 == 1) {
                // make some space for this hex-digit by
                // shifting the previous hex-digit with 4 bits to the left:
                code[bytesread >> 1] = (val | (tempbyte << 4));
                if (bytesread >> 1 != 5) {
                  // If we're at the checksum byte,
                  checksum ^= code[bytesread >> 1];
                  // Calculate the checksum... (XOR)
                };
              } else {
                tempbyte = val;
                // Store the first hex digit first...
              };
              bytesread++;
              // ready to read next digit
            }
          }
          // Output to Serial:
          if (bytesread == 12) {
            // removed code for clarity
            LCD.print("Check:");
            LCD.print(code[5], HEX);
            LCD.print(code[5] == checksum ? "-passed" : "-error");
          }
          bytesread = 0;
        }
      }
    }
    

    My Java/Android port is listening over a BluetoothSocket. I'm using the code from BlueTerm as the base, this code goes in the ConnectedThread. Apologies for all silly comments, but I'm still learning Java).

    //assume you have checksum as int and code as int array. it will overflow if bytes are used like above example
    public void run() {
      Log.d(TAG, "BEGIN mConnectedThread");
      byte[] buffer = new byte[1024];
      int bytes;
      // Keep listening to the InputStream while connected
      while (true) {
        Log.d(TAG, "Running");
        try {
          // Read from the InputStream
          bytes = mmInStream.read(buffer);
          for (int i = 0; i < bytes; i++) {
            Log.d(TAG, "Reading: " + i + " of " + bytes + " from input stream");
            byte b = buffer[i];
            try {
              if(bytesread >= 0) {
                //just printing ASCII
                char printableB = (char) b;
                if (b < 32 || b > 126) printableB = ' ';
                Log.d(TAG, "'" + Character.toString(printableB) + "' (" + Integer.toString(b) + ")");
                if((b == 0x0D)||(b == 0x0A)||(b == 0x03)||(b == 0x02)) {
                  // if header or stop bytes before the 10 digit reading
                  Log.e(TAG, i + " Unexpected header while processing character " + Integer.toString(b));
                } else {
                  // Do ASCII/Hex conversion
                  if ((b >= '0') && (b <= '9')) {
                    b = (byte) (b - '0');
                  } else if ((b >= 'A') && (b <= 'F')) {
                    b = (byte) (10 + b - 'A');
                  }
                  if ((bytesread & 1) == 1) {
                    //if isOdd(bytesread)
                  // make some space for this hex-digit by shifting the previous hex-digit with 4 bits to the left:
                  code[bytesread >> 1] = (b | (tempbyte << 4));
                  if (bytesread >> 1 != 5) {
                    // If we're not at the checksum byte,
                    checksum ^= code[bytesread >> 1];
                    // Calculate the checksum... (XOR)
                  }
                } else {
                  // Store the first hex digit first
                  tempbyte = b; 
                }
              }
              bytesread++;
            } else if(b == 2) {
              bytesread = 0;
              Log.d(TAG, "Header found!");
            }
            if(bytesread == 12) {
              String check = (code[5] == checksum ? "-passed" : "-error");
              String r = "";
              for(int j = 0; j < 5; j++){
                r += Integer.toString(code[i]);
              }
              Log.d(TAG, "Check:" + Integer.toString(code[5]) + check);
              init();
            } else if(bytesread > 12){
              Log.e(TAG, "Too many bytes!");
            }
          } catch (Exception e) {
            Log.e(TAG, i + " Exception while processing character " + Integer.toString(b), e);
          }
        }
        String a = buffer.toString();
        a = "";
      } catch (IOException e) {
        Log.e(TAG, "disconnected", e);
        connectionLost();
        break;
      }
    }
    Log.i(TAG, "END mConnectedThread");
    }
    
    0 讨论(0)
提交回复
热议问题