leosac / access-control

Leosac Access Control - Open Source Physical Access Control System
https://leosac.com
GNU Affero General Public License v3.0
240 stars 40 forks source link

Wiegand Calculation #122

Closed djarbz closed 3 years ago

djarbz commented 6 years ago

It took me a while to figure this one out, either I'm doing something wrong, or the LEOSAC card to HEX conversion is wrong.

I have noticed that LEOSAC inverts the Facility Code and Stamp Number. If my real facility code is 55, LEOSAC is looking for 200. Same for the stamp number.

Then I've also noticed that the parity calculation is backwards, even parity is calculated as odd and vice versa.

I have created a bash script to take a FC and Stamp number input and spit out the "proper" HEX for LEOSAC.

The second script does the reverse, takes a valid HEX input and spits out the FC & Stamp info.

#Convert Card data to Leosac

echo What is your facility code?
read real_fc_dec

echo What is your stamp number?
read real_stamp_dec

#Invert FC & Stamp for Leosac
leosac_fc_dec=$((255-real_fc_dec))
leosac_stamp_dec=$((65535-real_stamp_dec))

#Convert Decimal to Hex
leosac_fc_hex=$(echo "obase=16; $((leosac_fc_dec))" | bc)
leosac_stamp_hex=$(echo "obase=16; $((leosac_stamp_dec))" | bc)

#Convert Hex to Binary
leosac_data_hex=$leosac_fc_hex$leosac_stamp_hex
leosac_data_bin=$(echo "obase=2; ibase=16; $leosac_data_hex" | bc )

#Split Binary
data_first_ones=$(echo $leosac_data_bin | cut -c1-12 | tr -cd '1' | wc -c)
data_second_ones=$(echo $leosac_data_bin | rev | cut -c1-12 | tr -cd '1' | wc -c)

#Leosac parity is reversed
if [ $((data_first_ones%2)) -eq 0 ];
then
    p1=1
else
    p1=0
fi

if [ $((data_second_ones%2)) -eq 0 ];
then
    p2=0
else
    p2=1
fi

#Convert to final Hex
bin_buffer="000000"
leosac_bin=$p1$leosac_data_bin$p2$bin_buffer
leosac_hex=$(echo "obase=16; ibase=2; $leosac_bin" | bc )

echo Real card data: $real_fc_dec-$real_stamp_dec
echo Fake card data: $leosac_fc_dec-$leosac_stamp_dec
echo
echo FC Hex: $leosac_fc_hex
echo Stamp Hex: $leosac_stamp_hex
echo
echo Non-Parity Binary: $leosac_data_bin
echo
echo Even Parity Ones: $data_first_ones
echo Odd Parity Ones: $data_first_ones
echo
echo Even Parity: $p1
echo Odd Parity: $p2
echo
echo Parity Binary: $leosac_bin
echo Patity Hex: $leosac_hex
echo
#Format Hex for auth.xml
formatted_hex=$(echo $leosac_hex | sed 's/../&:/g; s/:$//')
echo Formatted Hex: $formatted_hex
#Convert Leosac to Card data

#Check for passed Hex
if [ $# -eq 0 ]; then
    echo What is the hex value?
    read input_hex
else
    input_hex=$1
fi

#Remove colons & capitalize
leosac_hex=$(echo ${input_hex//:} | tr a-z A-Z )

#Convert to Binary
leosac_bin=$(echo "obase=2; ibase=16; $leosac_hex" | bc )

#Check for stripped leading 0s
while [ $(echo -n $leosac_bin | wc -m) -lt 32 ]
do
    leosac_bin=0$leosac_bin
done

#Strip Parity
leosac_data_bin=$(echo "${leosac_bin:1:${#leosac_bin}-2}")

#Facility Code
leosac_fc_bin=$(echo $leosac_data_bin | cut -c1-8)

#Stamp Number
leosac_stamp_bin=$(echo $leosac_data_bin | cut -c9-24)

#Convert Leosac values to decimal
leosac_fc_dec=$(echo "obase=10; ibase=2; $leosac_fc_bin" | bc )
leosac_stamp_dec=$(echo "obase=10; ibase=2; $leosac_stamp_bin" | bc )

#Convert Leosac to actual data
real_fc_dec=$((255-leosac_fc_dec))
real_stamp_dec=$((65535-leosac_stamp_dec))
real_fc_hex=$(echo "obase=16; $((real_fc_dec))" | bc)
real_stamp_hex=$(echo "obase=16; $((real_stamp_dec))" | bc)

echo Card data: $real_fc_dec-$real_stamp_dec
#echo Fake card data: $leosac_fc_dec-$leosac_stamp_dec
echo
echo Real FC Hex: $real_fc_hex
echo Real Stamp Hex: $real_stamp_hex
echo
echo Non-Parity Binary: $leosac_data_bin
echo
echo Parity Binary: $leosac_bin
echo Parity Hex: $input_hex
Maxhy commented 3 years ago

Mhh not sure it is a software issue, that's an usual behavior with Wiegand :) If you invert D0 and D1, 00110111 become 11001000. So please be sure it is probably wired and inverse D0 and D1. This ticket is old now so I will close it but feel free to comment.