dmr_utils3/dmr_utils3/golay.py

100 lines
3.5 KiB
Python
Executable File

#!/usr/bin/env python
#
###############################################################################
# Copyright (C) 2016-2018 Cortney T. Buffington, N0MJS <n0mjs@me.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
###############################################################################
from bitarray import bitarray
from binascii import b2a_hex as ahex
from dmr_utils3.golay_tables import *
# Does anybody read this stuff? There's a PEP somewhere that says I should do this.
__author__ = 'Cortney T. Buffington, N0MJS'
__copyright__ = 'Copyright (c) 2016-2018 Cortney T. Buffington, N0MJS and the K0USY Group'
__credits__ = 'Jonathan Naylor, G4KLX who many parts of this were thankfully borrowed from'
__license__ = 'GNU GPLv3'
__maintainer__ = 'Cort Buffington, N0MJS'
__email__ = 'n0mjs@me.com'
X22 = 0x00400000 # vector representation of X^22
X18 = 0x00040000 # vector representation of X^18
X11 = 0x00000800 # vector representation of X^11
MASK12 = 0xfffff800 # auxiliary vector for testing
MASK8 = 0xfffff800 # auxiliary vector for testing
GENPOL = 0x00000c75 # generator polinomial, g(x)
# This routine currently uses hex strings of the precalculated codes.
# This generates them from the integer table for (20,8,7)
ENCSTR_2087 = [0 for x in range(256)]
for value in range(256):
ENCSTR_2087[value] = ENCODE_2087[value].to_bytes(2, 'big')
def get_synd_1987(_pattern):
aux = X18
if _pattern >= X11:
while _pattern & MASK8:
while not (aux & _pattern):
aux = aux >> 1
_pattern = _pattern ^ ((aux // X11) * GENPOL)
return _pattern
def get_synd_23127(_pattern):
aux = X22
if _pattern >= X11:
while _pattern & MASK12:
while not (aux & _pattern):
aux = aux >> 1
_pattern = _pattern ^ ((aux // X11) * GENPOL)
return _pattern
def decode_2087(_data):
bin_data = int(ahex(_data), 16)
syndrome = get_synd_1987(bin_data)
error_pattern = DECODE_1987[syndrome]
if error_pattern != 0x00:
bin_data = bin_data ^ error_pattern
return bin_data >> 12
def encode_2087(_data):
byte = ord(_data)
cksum = ENCODE_2087[byte]
return ( byte << 12 | (cksum & 0xFF) << 4 | cksum >> 12)
#------------------------------------------------------------------------------
# Used to execute the module directly to run built-in tests
#------------------------------------------------------------------------------
if __name__ == '__main__':
from time import time
# For testing the code
def print_hex(_list):
print(('[{}]'.format(', '.join(hex(x) for x in _list))))
to_decode = b'\x01\x2a\x59'
to_encode = b'\x12'
print((hex(decode_2087(to_decode))))
encoded = encode_2087(to_encode)
print((hex(encoded)))