How to transform Wiegand card ID into a Wiegand binary?

1.6k Views Asked by At

Wiegand Interface:

  • a card ID is made of a Facility Code and a Card Number;
  • the Facility Code represents the first 3 digits: 000
  • the Card Number represents the last 5 digits: 99999
  • now, we should take these numbers and transform them into binary and here lies the problem
  • the Facility Code needs to be an 8 bit long binary
  • the Card Number needs to be an 16 bit long binary
  • 99999 can't be represented on 16 bits.
  • what am I supposed to do now ?

I have made a class that takes any decimal and transforms it into a Card ID with its respective Facility Code and Card Number:

class Wiegand {
  private:
    std::vector<bool> wiegandArray = std::vector<bool>(26, false);
    uint8_t facilityCode;
    uint16_t cardNumber;
    void calculate(uint32_t dec) {
      // transform dec number into binary number using single bit shift operation
      // and store it in wiegandArray[]
      for (int i = 24; i > 0; --i) {
        wiegandArray[i] = dec & 1;
        dec >>= 1;
      }
      // check for parity of the first 12 bits
      bool even = 0;
      for(int i = 1; i < 13; i++) {
        even ^= wiegandArray[i];
      }
      // add 0 or 1 as first bit (leading parity bit - even) based on the number of 'ones' in the first 12 bits
      wiegandArray[0] = even;

      // check for parity of the last 12 bits
      bool odd = 1;
      for(int i = 13; i < 25; i++) {
        odd ^= wiegandArray[i];
      }
      // add 0 or 1 as last bit (trailing parity bit - odd) based on the number of 'ones' in the last 12 bits
      wiegandArray[25] = odd;
    }
  public:
    Wiegand(uint32_t id) {
      calculate(id);
      facilityCode = id >> 16;
      cardNumber = id & 0xffff;
    }
    //returns a 26 length std::vector<bool>
    std::vector<bool> getWiegandBinary() {
      return wiegandArray;
    }
    //returns uint8_t facilityCode
    uint8_t getFacilityCode() {
      return facilityCode;
    }
    //returns uint16_t cardNumber
    uint16_t getCardNumber() {
      return cardNumber;
    }
    //returns an 8 characters long String
    String getCardID() {
      String s1 = String(facilityCode);
      String s2 = String(cardNumber);
      String s3 = String(facilityCode);
      while(s1.length() < 3) {
        s1 = String(0) + s1;
      }
      while(s2.length() < 5) {
        s2 = String(0) + s2;
      }
      String s3 = s1 + s2;
      return s3;
    }
};

The problem is that a Wiegand Central will return the Card ID when you scan a card, not the Wiegand representation in Decimal. So I have to preserve that format. I need some hocus-pocus that takes 00099999 as a Card ID and not as a decimal representation as my Wiegand class.

Decimal 99999 is 000000011000011010011111 in 24 bit representation. This translates into:

  • Facility Code: 00000001 or 1;
  • Card Number: 1000011010011111 or 34463;
  • That means Card ID: 00134463.

I am trying like crazy to make an algorithm that takes the Card ID 00099999 and transform it so it can give me Facility Code: 000 and Card Number 99999 and then make this into a proper 26 bit Wiegand.

Right now I think its impossible to do this. What do you think ?

EDIT:

I think that card number 00099999 cannot even exist. I have not talked to any card vendor and I think that I should have because I am missing vital information regarding the format of a Card ID. I think that the Card ID can only be made as a concatenation of the Facility Code that ranges from 0 to 255 and Card Number that ranges from 0 to 65535. So the "biggest" Card ID that can exist is 25565535. If this is true, the input should be comprised of the Facility Code (0-255) and Card Number (0 - 65535) that will then form the Card Number and which I can easily transform into a Wiegand 26 bit.

String Class

0

There are 0 best solutions below