The script processes a raw HEX string input (representing an FDX-B transponder) and extracts relevant fields, such as the header, identification code, country code, data block status, animal application indicator, CRC checksum, and extended data block.
- Dynamic Imports: It dynamically imports required libraries (
binascii
,argparse
,termcolor
), displaying errors if any library is missing. - HEX Processing: It converts the input HEX string into binary and extracts the fields following the FDX-B protocol structure.
- Manufacturer Lookup: Based on the country code, it enriches the output by displaying the manufacturer's name (if available).
- Colorful Output: Uses the
termcolor
library to colorize the output fields for better readability. - Error Handling:
- If no HEX string is passed, it displays a usage guide and prompts the user to provide valid input.
- If an invalid HEX string is passed, it catches the error and prints a helpful message.
The script is run via the command line, and the user must provide the HEX string as an argument for it to process the data.
import sys
# Dynamically import required libraries
libnames = ['binascii', 'argparse', 'termcolor']
for libname in libnames:
try:
lib = __import__(libname)
except:
print(f"Failed to import {libname}: ", sys.exc_info())
else:
globals()[libname] = lib
# List of known manufacturers and their ISO codes
manufacturers = {
985: "Destron",
982: "Allflex",
981: "Datamars",
978: "Ordicam",
977: "Avid",
975: "Sokymat",
972: "Planet ID",
968: "AEG",
967: "Rfdynamics",
966: "PetCode",
965: "4D Technology Co. Ltd.",
963: "Korth Eletro Mecanica LTDA",
961: "Mannings I.A.I.D.",
959: "Global ID Technologies",
958: "Pet ID",
956: "Trovan Ltd.",
955: "Reseaumatique",
953: "Cromasa Identificacion electronica S.A.",
952: "JECTA"
}
# Function to process the HEX input
def process_hex(hex_string):
try:
# Remove spaces and convert hex string to binary
hex_clean = hex_string.replace(" ", "")
binary_data = bin(int(hex_clean, 16))[2:].zfill(len(hex_clean) * 4)
# Extract fields from the binary data
header = binary_data[:11] # 11-bit header
identification_data = binary_data[11:49] # 38-bit identification code
country_code_binary = binary_data[49:59] # 10-bit country code
data_block_status = binary_data[59] # 1-bit data block status
animal_indicator = binary_data[60] # 1-bit animal indicator
crc = binary_data[61:77] # 16-bit CRC
extended_data_block = binary_data[77:101] # 24-bit extended data block
# Convert fields to relevant formats
country_code = int(country_code_binary, 2)
identification_code = int(identification_data, 2)
# Enrich manufacturer information
manufacturer_name = manufacturers.get(country_code, "Unknown")
# Print the fields with color
print(termcolor.colored(f"Header: {header} (11-bit)", "yellow"))
print(termcolor.colored(f"Identification Code: {identification_code} (12-digit code)", "cyan"))
print(termcolor.colored(f"Country Code: {country_code} (Manufacturer: {manufacturer_name})", "green"))
print(termcolor.colored(f"Data Block Status: {data_block_status} (1-bit)", "yellow"))
print(termcolor.colored(f"Animal Application Indicator: {animal_indicator} (1-bit)", "cyan"))
print(termcolor.colored(f"CRC Checksum: {crc} (16-bit)", "red"))
print(termcolor.colored(f"Extended Data Block: {extended_data_block} (24-bit)", "green"))
except ValueError:
print(termcolor.colored("Error: Invalid HEX string. Please provide a valid HEX string.", "red"))
# Command-line argument parser with error handling
def main():
parser = argparse.ArgumentParser(description="Process raw HEX input from an FDX-B transponder.")
parser.add_argument("hex_string", nargs="?", help="The raw HEX string to process (e.g., 'C2 28 EE 12 E9 6F 00 01 00 00 00')")
args = parser.parse_args()
if not args.hex_string:
print(termcolor.colored("Error: No HEX string provided. Please provide a valid HEX string as a command-line argument.", "red"))
parser.print_help()
else:
process_hex(args.hex_string)
if __name__ == "__main__":
main()
-
Error Handling for Missing Input:
- If no string is passed, the script will display a usage message using
argparse.print_help()
along with an error message.
- If no string is passed, the script will display a usage message using
-
Error Handling for Invalid HEX Strings:
- If an invalid HEX string (i.e., a string that can't be converted to a valid hexadecimal number) is passed, it will catch the
ValueError
and print a user-friendly error message indicating the issue.
- If an invalid HEX string (i.e., a string that can't be converted to a valid hexadecimal number) is passed, it will catch the
-
argparse
Settings:nargs="?"
is used to allow the HEX string argument to be optional, and the script can then handle the case where it’s missing.
- If you pass a valid HEX string:
python process_transponder.py "C2 28 EE 12 E9 6F 00 01 00 00 00"
- If you pass an invalid HEX string:
python process_transponder.py "InvalidString"
- If no string is passed:
python process_transponder.py
Error: No HEX string provided. Please provide a valid HEX string as a command-line argument.
usage: process_transponder.py [-h] [hex_string]
Process raw HEX input from an FDX-B transponder.
positional arguments:
hex_string The raw HEX string to process (e.g., 'C2 28 EE 12 E9 6F 00 01 00 00 00')
optional arguments:
-h, --help show this help message and exit
Error: Invalid HEX string. Please provide a valid HEX string.
This ensures that the script is robust, handles errors gracefully, and gives clear feedback to the user when something is wrong.