Skip to content

Instantly share code, notes, and snippets.

@bjonnh
Created December 7, 2024 05:28
Show Gist options
  • Save bjonnh/d2267917480c2f8b8735cd65f5c07405 to your computer and use it in GitHub Desktop.
Save bjonnh/d2267917480c2f8b8735cd65f5c07405 to your computer and use it in GitHub Desktop.
import random
def parse_wiegand_32(binary_str):
"""
Parse a 32-bit Wiegand code
Args:
binary_str (str): 32-bit binary string
Returns:
dict: Contains parity check result, facility code, and card number
"""
if len(binary_str) != 32:
raise ValueError("Input must be 32 bits long")
even_parity = int(binary_str[0])
facility_code = int(binary_str[1:17], 2)
card_number = int(binary_str[17:31], 2)
odd_parity = int(binary_str[31])
even_data = binary_str[1:17]
even_count = even_data.count('1')
even_parity_check = (even_count + even_parity) % 2 == 0
odd_data = binary_str[17:31]
odd_count = odd_data.count('1')
odd_parity_check = (odd_count + odd_parity) % 2 == 1
return {
'facility_code': facility_code,
'card_number': card_number,
'parity_check_passed': even_parity_check and odd_parity_check,
'even_parity_check': even_parity_check,
'odd_parity_check': odd_parity_check
}
def create_wiegand_32(facility_code, card_number):
"""
Create a 32-bit Wiegand code from facility code and card number
Args:
facility_code (int): Facility code (16 bits max)
card_number (int): Card number (14 bits max)
Returns:
str: 32-bit Wiegand binary string
"""
if not (0 <= facility_code <= 0xFFFF):
raise ValueError("Facility code must be between 0 and 65535")
if not (0 <= card_number <= 0x3FFF):
raise ValueError("Card number must be between 0 and 16383")
facility_bits = format(facility_code, '016b')
card_bits = format(card_number, '014b')
even_count = facility_bits.count('1')
even_parity = '0' if even_count % 2 == 0 else '1'
odd_count = card_bits.count('1')
odd_parity = '1' if odd_count % 2 == 0 else '0'
return even_parity + facility_bits + card_bits + odd_parity
def test_wiegand_conversion(num_tests=10):
"""
Test the Wiegand conversion functions with random numbers
Args:
num_tests (int): Number of random tests to perform
"""
print(f"Running {num_tests} random tests...")
print("-" * 50)
all_tests_passed = True
for i in range(num_tests):
# Generate random valid values
facility = random.randint(0, 0xFFFF) # 16 bits max
card = random.randint(0, 0x3FFF) # 14 bits max
try:
# Create Wiegand code
wiegand = create_wiegand_32(facility, card)
# Parse it back
parsed = parse_wiegand_32(wiegand)
# Verify results
test_passed = (facility == parsed['facility_code'] and
card == parsed['card_number'] and
parsed['parity_check_passed'])
print(f"\nTest #{i + 1}:")
print(f"Original: Facility={facility}, Card={card}")
print(f"Wiegand: {wiegand}")
print(f"Parsed: Facility={parsed['facility_code']}, Card={parsed['card_number']}")
print(f"Parity Check: {'Passed' if parsed['parity_check_passed'] else 'Failed'}")
print(f"Test Result: {'✓ Passed' if test_passed else '✗ Failed'}")
if not test_passed:
all_tests_passed = False
except ValueError as e:
print(f"\nTest #{i + 1} raised an error: {e}")
all_tests_passed = False
print("\n" + "=" * 50)
print(f"Final Result: {'All tests passed!' if all_tests_passed else 'Some tests failed!'}")
print("=" * 50)
if __name__ == "__main__":
# Set random seed for reproducibility (optional)
random.seed(42)
test_wiegand_conversion()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment