Created
December 7, 2024 05:28
-
-
Save bjonnh/d2267917480c2f8b8735cd65f5c07405 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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