istrain-public: from-scratch build of a passive RF train detector
Public community release. The complete working system — DSP + decoders (scripts/), web dashboard + API (dashboard/), container stack (docker/), config templates (config/) — plus APOCALYPSE-EDITION.md, the full build guide for a human or a coding agent. GPLv3 (PyEOT dependency). Scrubbed of all secrets, internal IPs, hostnames, and location detail. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
PyEOT End-of-Train Device Decoder
|
||||
Copyright (c) 2018 Eric Reuter
|
||||
|
||||
This source file is subject of the GNU general public license.
|
||||
|
||||
history: 2018-08-09 Initial Version
|
||||
|
||||
purpose: Misc. functions used by eot_decoder.py
|
||||
|
||||
Function XOR() and mod2div() adapted from:
|
||||
https://www.geeksforgeeks.org/cyclic-redundancy-check-python/
|
||||
"""
|
||||
|
||||
|
||||
# XOR two strings of bytes representing binary symbols
|
||||
def xor(a, b):
|
||||
result = []
|
||||
for i in range(len(b)):
|
||||
if a[i] == b[i]:
|
||||
result.append('0')
|
||||
else:
|
||||
result.append('1')
|
||||
return ''.join(result)
|
||||
|
||||
|
||||
# Reverse string
|
||||
def reverse(data):
|
||||
return ''.join(data[::-1])
|
||||
|
||||
|
||||
# Perform modulo-2 division on two strings of binary symbols
|
||||
def mod2div(dividend, divisor):
|
||||
|
||||
# Number of bits to be XORed at a time.
|
||||
pick = len(divisor)
|
||||
|
||||
# Slicing the dividend to appropriate
|
||||
# length for particular step
|
||||
tmp = dividend[0:pick]
|
||||
|
||||
while pick < len(dividend):
|
||||
|
||||
if tmp[0] == '1':
|
||||
|
||||
# replace the dividend by the result
|
||||
# of XOR and pull 1 bit down
|
||||
tmp = xor(divisor[1:], tmp[1:]) + dividend[pick]
|
||||
|
||||
else: # If leftmost bit is '0'
|
||||
# If the leftmost bit of the dividend (or the
|
||||
# part used in each step) is 0, the step cannot
|
||||
# use the regular divisor; we need to use an
|
||||
# all-0s divisor.
|
||||
tmp = xor(('0'*pick)[1:], tmp[1:]) + dividend[pick]
|
||||
|
||||
# increment pick to move further
|
||||
pick += 1
|
||||
|
||||
# For the last n bits, we have to carry it out
|
||||
# normally as increased value of pick will cause
|
||||
# Index Out of Bounds.
|
||||
if tmp[0] == '1':
|
||||
tmp = xor(divisor[1:], tmp[1:])
|
||||
else:
|
||||
tmp = xor(('0'*pick)[1:], tmp[1:])
|
||||
|
||||
remainder = tmp
|
||||
return remainder
|
||||
|
||||
|
||||
# Calculate BCH checkbits
|
||||
def checkbits(data, key):
|
||||
appended_data = data + '0'*(len(key)-1) # Appends n-1 zeros at end of data
|
||||
remainder = mod2div(appended_data, key)
|
||||
return ''.join(remainder)
|
||||
Reference in New Issue
Block a user