update CRC function
This commit is contained in:
parent
28e3a641a5
commit
1ccd4fd83b
@ -19,36 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
import math
|
import math
|
||||||
import util
|
import util
|
||||||
|
from util import crc
|
||||||
|
|
||||||
def checksum(msg):
|
|
||||||
"""CRC check the ADS-B message
|
|
||||||
Args:
|
|
||||||
msg (string): 28 bytes hexadecimal message string
|
|
||||||
Returns:
|
|
||||||
bool: Checksum passed or not
|
|
||||||
"""
|
|
||||||
if len(msg) == 28:
|
|
||||||
offset = 0
|
|
||||||
elif len(msg) == 14:
|
|
||||||
offset = 112-56
|
|
||||||
else:
|
|
||||||
# raise exception
|
|
||||||
return False
|
|
||||||
|
|
||||||
msgbin = util.hex2bin(msg)
|
|
||||||
checksum = int(msg[22:28], 16)
|
|
||||||
|
|
||||||
crc = 0
|
|
||||||
for i in xrange(len(msgbin)):
|
|
||||||
# print msgbin[i]
|
|
||||||
if int(msgbin[i]):
|
|
||||||
crc ^= util.MODES_CHECKSUM_TABLE[i+offset]
|
|
||||||
|
|
||||||
if crc == checksum:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def df(msg):
|
def df(msg):
|
||||||
|
@ -18,29 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import util
|
import util
|
||||||
|
from util import crc
|
||||||
|
|
||||||
def crc(msg):
|
|
||||||
"""Calculate the cyclic redundancy checksum of an message
|
|
||||||
Args:
|
|
||||||
msg (String): 28 or 14 bytes hexadecimal message string
|
|
||||||
Returns:
|
|
||||||
int: checksum in integer
|
|
||||||
"""
|
|
||||||
if len(msg) == 28:
|
|
||||||
offset = 0
|
|
||||||
elif len(msg) == 14:
|
|
||||||
offset = 112-56
|
|
||||||
else:
|
|
||||||
raise RuntimeError("wrong message length, need to be 28 or 14 bytes")
|
|
||||||
|
|
||||||
msgbin = util.hex2bin(msg)
|
|
||||||
|
|
||||||
crc = 0
|
|
||||||
for i in xrange(len(msgbin)):
|
|
||||||
if int(msgbin[i]):
|
|
||||||
crc ^= util.MODES_CHECKSUM_TABLE[i+offset]
|
|
||||||
return crc
|
|
||||||
|
|
||||||
|
|
||||||
def df(msg):
|
def df(msg):
|
||||||
@ -71,7 +49,7 @@ def icao(msg):
|
|||||||
# raise RuntimeError("Message DF must be in (4, 5, 20, 21)")
|
# raise RuntimeError("Message DF must be in (4, 5, 20, 21)")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
c0 = crc(msg)
|
c0 = util.bin2int(crc(msg, encode=True))
|
||||||
c1 = util.hex2int(msg[-6:])
|
c1 = util.hex2int(msg[-6:])
|
||||||
icao = '%06X' % (c0 ^ c1)
|
icao = '%06X' % (c0 ^ c1)
|
||||||
return icao
|
return icao
|
||||||
|
@ -19,36 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
MODES_CHECKSUM_TABLE = [
|
# the polynominal generattor code for CRC
|
||||||
0x3935ea, 0x1c9af5, 0xf1b77e, 0x78dbbf,
|
GENERATOR = "1111111111111010000001001"
|
||||||
0xc397db, 0x9e31e9, 0xb0e2f0, 0x587178,
|
|
||||||
0x2c38bc, 0x161c5e, 0x0b0e2f, 0xfa7d13,
|
|
||||||
0x82c48d, 0xbe9842, 0x5f4c21, 0xd05c14,
|
|
||||||
0x682e0a, 0x341705, 0xe5f186, 0x72f8c3,
|
|
||||||
0xc68665, 0x9cb936, 0x4e5c9b, 0xd8d449,
|
|
||||||
0x939020, 0x49c810, 0x24e408, 0x127204,
|
|
||||||
0x093902, 0x049c81, 0xfdb444, 0x7eda22,
|
|
||||||
0x3f6d11, 0xe04c8c, 0x702646, 0x381323,
|
|
||||||
0xe3f395, 0x8e03ce, 0x4701e7, 0xdc7af7,
|
|
||||||
0x91c77f, 0xb719bb, 0xa476d9, 0xadc168,
|
|
||||||
0x56e0b4, 0x2b705a, 0x15b82d, 0xf52612,
|
|
||||||
0x7a9309, 0xc2b380, 0x6159c0, 0x30ace0,
|
|
||||||
0x185670, 0x0c2b38, 0x06159c, 0x030ace,
|
|
||||||
0x018567, 0xff38b7, 0x80665f, 0xbfc92b,
|
|
||||||
0xa01e91, 0xaff54c, 0x57faa6, 0x2bfd53,
|
|
||||||
0xea04ad, 0x8af852, 0x457c29, 0xdd4410,
|
|
||||||
0x6ea208, 0x375104, 0x1ba882, 0x0dd441,
|
|
||||||
0xf91024, 0x7c8812, 0x3e4409, 0xe0d800,
|
|
||||||
0x706c00, 0x383600, 0x1c1b00, 0x0e0d80,
|
|
||||||
0x0706c0, 0x038360, 0x01c1b0, 0x00e0d8,
|
|
||||||
0x00706c, 0x003836, 0x001c1b, 0xfff409,
|
|
||||||
0x000000, 0x000000, 0x000000, 0x000000,
|
|
||||||
0x000000, 0x000000, 0x000000, 0x000000,
|
|
||||||
0x000000, 0x000000, 0x000000, 0x000000,
|
|
||||||
0x000000, 0x000000, 0x000000, 0x000000,
|
|
||||||
0x000000, 0x000000, 0x000000, 0x000000,
|
|
||||||
0x000000, 0x000000, 0x000000, 0x000000
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def hex2bin(hexstr):
|
def hex2bin(hexstr):
|
||||||
@ -70,4 +42,32 @@ def hex2int(hexstr):
|
|||||||
def df(msg):
|
def df(msg):
|
||||||
"""Decode Downlink Format vaule, bits 1 to 5."""
|
"""Decode Downlink Format vaule, bits 1 to 5."""
|
||||||
msgbin = hex2bin(msg)
|
msgbin = hex2bin(msg)
|
||||||
return bin2int(msgbin[0: 5])
|
return bin2int(msgbin[0:5])
|
||||||
|
|
||||||
|
|
||||||
|
def crc(msg, encode=False):
|
||||||
|
"""Mode-S Cyclic Redundancy Check
|
||||||
|
Detect if bit error occurs in the Mode-S message
|
||||||
|
Args:
|
||||||
|
msg (string): 28 bytes hexadecimal message string
|
||||||
|
encode (bool): True to encode the date only and return the checksum
|
||||||
|
Returns:
|
||||||
|
string: message checksum, or partity bits (encoder)
|
||||||
|
"""
|
||||||
|
|
||||||
|
msgbin = list(hex2bin(msg))
|
||||||
|
|
||||||
|
if encode:
|
||||||
|
msgbin[-24:] = ['0'] * 24
|
||||||
|
|
||||||
|
# loop all bits, except last 24 piraty bits
|
||||||
|
for i in range(len(msgbin)-24):
|
||||||
|
# if 1, perform modulo 2 multiplication,
|
||||||
|
if msgbin[i] == '1':
|
||||||
|
for j in range(len(GENERATOR)):
|
||||||
|
# modulo 2 multiplication = XOR
|
||||||
|
msgbin[i+j] = str((int(msgbin[i+j]) ^ int(GENERATOR[j])))
|
||||||
|
|
||||||
|
# last 24 bits
|
||||||
|
reminder = ''.join(msgbin[-24:])
|
||||||
|
return reminder
|
||||||
|
16
tests/run.py
16
tests/run.py
@ -7,6 +7,22 @@ sys.path.insert(0, parentdir)
|
|||||||
import pyModeS as pms
|
import pyModeS as pms
|
||||||
from pyModeS import adsb
|
from pyModeS import adsb
|
||||||
from pyModeS import ehs
|
from pyModeS import ehs
|
||||||
|
from pyModeS import util
|
||||||
|
|
||||||
|
|
||||||
|
# === TEST common functions ===
|
||||||
|
def test_hex2bin():
|
||||||
|
assert util.hex2bin('6E406B') == "011011100100000001101011"
|
||||||
|
|
||||||
|
|
||||||
|
def test_crc():
|
||||||
|
# crc decoder
|
||||||
|
checksum = util.crc("8D406B902015A678D4D220AA4BDA")
|
||||||
|
assert checksum == "000000000000000000000000"
|
||||||
|
|
||||||
|
# crc encoder
|
||||||
|
parity = util.crc("8D406B902015A678D4D220AA4BDA", encode=True)
|
||||||
|
assert util.hex2bin("AA4BDA") == parity
|
||||||
|
|
||||||
|
|
||||||
# === TEST ADS-B package ===
|
# === TEST ADS-B package ===
|
||||||
|
Loading…
Reference in New Issue
Block a user