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 util
|
||||
|
||||
|
||||
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
|
||||
from util import crc
|
||||
|
||||
|
||||
def df(msg):
|
||||
|
@ -18,29 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
import util
|
||||
|
||||
|
||||
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
|
||||
from util import crc
|
||||
|
||||
|
||||
def df(msg):
|
||||
@ -71,7 +49,7 @@ def icao(msg):
|
||||
# raise RuntimeError("Message DF must be in (4, 5, 20, 21)")
|
||||
return None
|
||||
|
||||
c0 = crc(msg)
|
||||
c0 = util.bin2int(crc(msg, encode=True))
|
||||
c1 = util.hex2int(msg[-6:])
|
||||
icao = '%06X' % (c0 ^ c1)
|
||||
return icao
|
||||
|
@ -19,36 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import math
|
||||
|
||||
MODES_CHECKSUM_TABLE = [
|
||||
0x3935ea, 0x1c9af5, 0xf1b77e, 0x78dbbf,
|
||||
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
|
||||
]
|
||||
# the polynominal generattor code for CRC
|
||||
GENERATOR = "1111111111111010000001001"
|
||||
|
||||
|
||||
def hex2bin(hexstr):
|
||||
@ -70,4 +42,32 @@ def hex2int(hexstr):
|
||||
def df(msg):
|
||||
"""Decode Downlink Format vaule, bits 1 to 5."""
|
||||
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
|
||||
from pyModeS import adsb
|
||||
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 ===
|
||||
|
Loading…
Reference in New Issue
Block a user