update CRC function

This commit is contained in:
junzis 2016-03-23 11:35:20 +01:00
parent 28e3a641a5
commit 1ccd4fd83b
4 changed files with 50 additions and 85 deletions

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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 ===