0

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

  • How come the 16 bit limit for the card number? – domsson Jan 23 '20 at 10:56
  • You might want to tag this question with "wiegand" if that what this question is about – Jerome Reinländer Jan 23 '20 at 10:56
  • @domsson Wiki says: `The original Wiegand format had one parity bit, 8 bits of facility code, 16 bits of ID code, and a trailing parity bit for a total of 26 bits.` The original is the 26 bit one. That is the format. – GeorgicaFaraFrica Jan 23 '20 at 10:59
  • I read your question somehow like: How should I store a value of 17 bits into a storage of 16 bits? Eehhh... That's impossible. It's impossible like a Perpetuum Mobile is impossible. There are YouTube videos which try to convince about the opposite but they all are lieing. Mostly there is a secret trick which is not published. I assume that's the same about your Card ID 99999. You could ask the Card vendor or producer. I even could imagine that the card uses intentionally an invalid code (to whatever purpose). It sounds like my phone no. 0123456789 I prefer to use in Web shops... ;-) – Scheff's Cat Jan 23 '20 at 11:14
  • 1
    @Scheff That is what I am thinking right now. 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 info 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`. – GeorgicaFaraFrica Jan 23 '20 at 11:23
  • Yepp. Or, there is that secret trick you have to find out. That trick either should be documented somewhere or is secret intentionally to keep the public away from certain stuff. E.g. there is a "silent" 1 in normalized floating point mantissas which is not stored in the bits but assumed in decoding. That's what I would consider as trick - in this case a documented. In your case, it could be that the parity bit is abused to signal a missing 1. Normally, I would consider the parity for error checking hence the "abused". Only speculation... I've read the first time about Wiegand in your Q. – Scheff's Cat Jan 23 '20 at 11:29

0 Answers0