<!DOCTYPE html >
<html> <head> <title>J Thomas Stokkeland - Code</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <link rel="stylesheet" type="text/css" href="code.css" />

  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script type="text/javascript"><!--

    $(document).ready(function(){

          $license=false;
      $("#license").click(function(){
         if ($license) {
          $("#gpl3").hide();
              $license=false;
        }
        else {
           $("#gpl3").show();
              $license=true;
        }
      });

    });


 --></script>

 </head>
 <body>
  <div id="content">
  <h2>Thomas Stokkeland</h2>
  <h1>RFID &amp; HID Stuff - 33 bit generic</h1>
  <hr />
  <h4>License: GNU General Public License version 3 (GPL v3)
    <a href="rfid_33bitgeneric.phps" target="_new">Click to view source</a>
  </h4>
  <p class="small">Copyright 2014 J T Stokkeland.
    <u id="license">Click to view license</u>.
  </p>
  <div id="gpl3" style="display: none;"><pre>
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program, <a 
        href="gpl.txt" target="_new">Click Here for full license details</a>. 
    If not, see <a 
        target="_new" href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>. 
   </pre>
  </div>
  <p class="small">
   This came about due to the installation of an Axis A1001 entry system I was involved in,
   an attempt to pre-populate the Raw card data field for users was not easy. 
   With the help of Peter from <a href="http://www.securitek.com/" target="_new">securitek</a>, 
   I was all to dig into and figure out a way, which resulted in this code piece.
   I am still not entirely sure of if this is the exact correct way, I was able to determine
   for sure that it is a 33 bit card we where uising, and thait it is is NOT like 
    some other 33 bit standards out there which appear to 
   use overlap in parity data checks,
   but rather similar to the old 26bit standard, data split in 15/16 bit bitwise parity check.
   I am no pro on how to code such, it is very likely the code could be much more elegant using some
   more efficient mathematics, but oh well - this will have to do for now.
   Thanks to <a href="http://www.pagemac.com/azure/data_formats.php" target="_new">PageMac.com</a> for
   the basic info on this stuff - it has proven very hard to find anything good and complete.
  </p>
  <hr />

  <div id="theform">
   <form action="rfid_33bitgeneric.php" method="post">
   <?php

    usleep
(1000); // prevent automated junk from taking down my server

      
if (!empty($_REQUEST['faccode'])) $faccode = (int) $_REQUEST['faccode'];
    else 
$faccode 0;

      if (!empty(
$_REQUEST['cardcodes'])) $ccarray explode("\n",trim($_REQUEST['cardcodes']));
    else 
$ccarray = array('1234567');

        
$cardcodes '';
        foreach (
$ccarray as $c) if ((int) $c$cardcodes .= (int) $c ."\n";


   
?>
    <p>Facility Code 7bit (0 to 63):
        <input type="text" name="faccode" value="<?php echo $faccode?>" /></p>
    <p>Card Codes 24bit (0 to 16777215) - one per line:<br />
        <textarea name="cardcodes" cols="10" rows="5"><?php 
        
echo trim($cardcodes); 
    
?></textarea>
    </p>

    <p><input type="submit" name="GetrDone" value="Submit"</p>

   </form>

   <p><b>Results</b><br />
   <span class="small">(Take with a grain of salt, havent found a spec that confirms it is done correctly,
    it is basically based on trial and error from a small sample in a single facility code)
    <br /></span>

   <?php
     
if ($ccarray) foreach ($ccarray as $c) if ((int) $c)
        echo 
'<br />'.((int) $c) .' : 'encode_33bit_generic($c,$faccode)."\n";
   
?>
   </p>

  </div>

  <p> &nbsp; </p>



  <p class="small txtcenter">

     <a href="./?ref=rfid">[ <u>Code</u> ]</a>
    &nbsp;
    &nbsp;
    &copy; <a href="../">Jon Thomas Stokkeland &nbsp;

     [ <u>Home</u> ] </a>  
    
    &nbsp;
    <a href="../it/"> [ <u>Information Technology</u> ] </a>
    &nbsp;
    <a href="http://www.linkedin.com/in/stokkeland"> [ <u>Linked In</u> ] </a>



  </p>
  
  </div>
 </body>
</html>
<?php




// ---------------------------------------------------------
// Code/Functions writen by and copyright J.T.Stokkeland 2014
// Licensed under GNU GPL v3.
// ---------------------------------------------------------

// Simple function to do the following
//  - convert facility code to a 7 bit binary
//  - convert card code to a 24 bit binary
//  - put them together in one binary (string)
//  - do a bitwise even-parity check on the first 15 bits
//  - do a bitwise odd-parity check on the last 16 bits
//  - put together as follows for a 33 bit binary (string)
//    - 1 bit even parity
//    - 7 bit facility
//    - 24 bit card
//    - 1 bit odd parity
//  - produce a hex string from the binary 33 bit value
//
// This may not even be the correct way, but appears to have worked
// for me for now...
//
function encode_33bit_generic ($cardcode,$faccode)
{
  
$new24 str_pad(decbin($cardcode),24,'0',STR_PAD_LEFT);
  
$new7 str_pad(decbin($faccode),7,'0',STR_PAD_LEFT);

  
$s $new7.$new24;

  
$ebin=substr($s,0,15);
  
$obin=substr($s,-16);

  
$even bwpar_even($ebin) ? 0;
  
$odd bwpar_odd($obin) ? 0;

  
$news $even.$new7.$new24.$odd;
  
$newhex str_pad(dechex(bindec($news)),10,'0',STR_PAD_LEFT);

  if (
0)   // Use this to DEBUG or something if you need to
  
{
     echo 
"
       Facility code: 
$faccode
       Card code: 
$cardcode
       Hex code: 
$newhex
       Binary Data only: 
$s
       Binary done:      
$news
       Even Bin: 
$ebin  $even  ".substr_count($ebin,'1')."
       Odd Bin:  
$obin  $odd   ".substr_count($obin,'1')."
     "
;
  }
  return 
$newhex;
}

// silly duct tape functions for the parity checks
function bwpar_even($bin) { return ( substr_count($bin,'1') % ); }
function 
bwpar_odd($bin) { return ( (substr_count($bin,'1')+1) % ); }





?>