Exemple #1
0
def readFile0BC(context):
    filedata = None
    with open(context.filepath, 'rb') as f:
        filedata = f.read()

    bd = BinData(filedata)
    print('file size =', bd.dataSize())

    h = readHeader0BC(bd)
    context.header = h
    pprint(h)

    if h.maybeDataType == 1:
        assert(context.expectedFormat == 0x10)
        # assert(h.countRecords == 0)
        readPhysicalCollision0BC(bd, context)
    elif h.maybeDataType != 0:
        print('Yet unknown and unexpected header')
        assert(False)
    else:
        if context.expectedFormat == 0x12:
            readRecords0BC_format_12(bd, context)
        else:
            readRecords0BC(bd, context)



    print(bd.tell(), bd.dataSize())
Exemple #2
0
def main():
    parser = argparse.ArgumentParser(
        description=
        "-= Encoder/Decoder of convolutional codes.\nAuthor: Jozef Knaperek =-\n"
    )
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('-e',
                       '--encode',
                       action='store_true',
                       help='encode data with convolutional code')
    group.add_argument('-d',
                       '--decode',
                       action='store_true',
                       help='decode data using Viterbi algorithm')

    def make_bindata(arg):
        return BinData(arg)

    make_bindata.__name__ = 'input data'
    parser.add_argument('-i',
                        '--input',
                        type=make_bindata,
                        help='input data bit-stream (instead of using stdin)')

    def make_pols_list(arg):
        pols = [int(pol, 2) for pol in arg.split(',')]
        if min(map(ones_count, pols)) < 2:
            raise ValueError(
                'Every valid polynomial must have at least two binary 1s')
        return pols

    make_pols_list.__name__ = 'polynomials list'
    parser.add_argument(
        'polynomials',
        help=
        'comma separated list of binnary polynomials (of at least two binary 1s in each)',
        type=make_pols_list)

    args = parser.parse_args()

    try:
        input_data = args.input or BinData(sys.stdin.read())
    except ValueError:
        sys.exit('Invalid input data: ' + stdin_input)

    if args.encode:  # encode
        print(Transitions(args.polynomials).encode(input_data))
    else:  # decode
        if len(input_data) % len(args.polynomials):
            sys.exit(
                'Decoding error: The number of data bits ({}) is not multiple of the number of polynomials ({})!'
                .format(len(input_data), len(args.polynomials)))
        print(args.polynomials)
        print(Transitions(args.polynomials).decode(input_data))
Exemple #3
0
    def __init__(self,bstream,entry_type,size,offset=None):
        """
        Parse an entry list from a bytestream
        entry_type should be any Entry type generated
        with Entry.create()
        """

        self.data = []
        self.corrupted = False

        self.type = entry_type

        #Set the entry offset
        if offset == None:
            self.offset = BinData(4)
            self.offset.init_data_from_int(bstream.offset)
        elif issubclass(offset.__class__,(types.IntType,)):
            self.offset = BinData(4)
            self.offset.init_data_from_int(offset)
        elif issubclass(offset.__class__,(BinData,)):
            self.offset = offset
        else:
            raise Exception('Invalid type for EntryList offset: %s' % offset.__class__)

        bstream.seek(int(self.offset))

        if issubclass(size.__class__,(types.IntType,)):
            self.size = BinData(4)
            self.size.init_data_from_int(size)
        elif issubclass(size.__class__,(BinData,)):
            self.size = size
        else:
            raise Exception('Invalid type for EntryList size: %s' % size.__class__)


        for i in xrange(int(self.size)):
            self.data.append(self.type(bstream))

            if bstream.exhausted:
                self.corrupted = True
                break
Exemple #4
0
    def decode(self, parity_sequence_bindata):
        """ Decodes convolutional code using the Viterbi algorithm. Public method (API). """
        gen = self.extract_parity_sequence(parity_sequence_bindata)
        state = 0  # initial state

        INF = float('inf')  # constant definition

        class Node():
            def __init__(self, metric=INF, bindata=None):
                self.metric = metric
                self.bindata = bindata or BinData(0, 0)

        # init trellis
        olds = [Node(INF, BinData(0, 0))
                for i in range(self.n_states)]  # aktualna metrika, data bits
        news = [Node(None, None) for i in range(self.n_states)
                ]  # nova metrika, data bits (with added one new bit)
        olds[0].metric = 0  # set metrics of first state to 0

        # iterate through parities in encoded data (parity sequence)
        for parity in gen:
            # initialize news
            for new in news:
                new.metric = INF  # set new PM to infinity

            # choose best paths for new step
            for i in range(self.n_states):
                for bit in (0, 1):
                    t = self.states[i][bit].new_state
                    p = self.states[i][bit].parity
                    hd = hamming_distance(p, parity)

                    new_PM = olds[i].metric + hd  # compute candidate PM
                    if new_PM < news[
                            t].metric:  # if this new candidate is better than existing new candidate
                        news[t].metric = new_PM
                        news[t].bindata = olds[i].bindata + bit

            # update "column" in trellis with best paths chosen in previous step and prepare for next iteration
            for i in range(self.n_states):
                olds[i].metric = news[i].metric
                olds[i].bindata = news[i].bindata

        # Finalization
        # Get state with best PM
        best_state, best_PM = None, INF
        for old in olds:
            if old.metric < best_PM:
                best_PM = old.metric
                best_state = old

        # Decoded databits:
        return best_state.bindata
Exemple #5
0
    def _prepare_stream(self,bstream,offset):
        """
        Initialize the offset and mode the stream to it.
        The offset should a BinData object to allow references to it
        As so, an update in an offset will update all its the references.
        """
        if offset == None:
            offset = bstream.offset

        if issubclass(offset.__class__,(types.IntType,)):
            self.offset = BinData(4)
            self.offset.init_data_from_int(offset)
        elif issubclass(offset.__class__,(BinData,)):
            self.offset = offset
        elif (issubclass(offset.__class__,(Entry,)) and
              '__int__' in dir(offset)):
            self.offset = offset
        else:
            raise Exception('Invalid type for EntryList offset (%s) in class %s' % 
                            (offset,self))

        bstream.seek(int(self.offset))
Exemple #6
0
 def make_bindata(arg):
     return BinData(arg)
Exemple #7
0
 def __init__(self, metric=INF, bindata=None):
     self.metric = metric
     self.bindata = bindata or BinData(0, 0)
Exemple #8
0
 def encode(self, bindata):
     """ Encodes data using convolutional code. Public method (API). """
     parity_sequence = BinData(0, 0)
     for parity in self.generate_parities(bindata):
         parity_sequence += BinData(parity, self.parity_len)
     return parity_sequence