Esempio n. 1
0
def rs_fix(data):
    #	data=data+bytearray([0]*elen)
    data = data + ([0] * elen)
    r = range(len(data) - elen, len(data))
    try:
        (cmsg, crs) = reedsolo.rs_correct_msg(data, nsym, fcr, generator, r)
    except:
        return (False, None, None)
    return (True, cmsg, crs)
Esempio n. 2
0
def rs_fix(data):
#	data=data+bytearray([0]*elen)
	data=data+([0]*elen)
	r=list(range(len(data)-elen,len(data)))
	try:
		(cmsg,crs)=reedsolo.rs_correct_msg(data,nsym+elen,fcr,generator,erase_pos=r)
	except reedsolo.ReedSolomonError:
		return (False,None,None)
	except ZeroDivisionError:
		return (False,None,None)
	return (True,cmsg,crs[:nsym])
Esempio n. 3
0
def hread(tout):
    start = time.time()
    while tout <= 0 or (time.time() - start) < tout:
        if ser.inWaiting() >= 3:
            try:
                header = reedsolo.rs_correct_msg(ser.read(3), 2)[0]

                return ord(header)
            except reedsolo.ReedSolomonError as e:
                return 'Error'

    ser.flushInput
    return None
Esempio n. 4
0
def decode(blocks, nsym=DEFAULT_NSYM):

    last_chunk = end_of_stream(BLOCK_SIZE - nsym - 1)
    for block in blocks:
        assert len(block) == BLOCK_SIZE
        chunk = bytearray(rs_correct_msg(block, nsym))
        if chunk == last_chunk:
            log.info('EOF encountered')
            return  # end of stream

        size = chunk[0]
        payload = chunk[1:]
        if size > len(payload):
            raise ValueError('Invalid chunk', size, len(payload), payload)

        yield payload[:size]
Esempio n. 5
0
def main():
    # Reed message from file and encode
    msg = open('data/input.txt', 'r').read().encode()
    msgs = split_str(msg, n - 2 * t)

    # Open timer file in append mode
    encode_time = open('data/encode_time_python.csv', 'a')
    decode_time = open('data/decode_time_python.csv', 'a')

    # Generate table and generater polynomial
    # prim = rs.find_prime_polys(c_exp=m, fast_primes=True, single=True)
    # rs.init_tables(c_exp=m, prim=prim)
    rs.init_tables(0x14d)
    gen = rs.rs_generator_poly_all(n)

    for i in range(runs):
        # Encode msg
        msgeccs = []
        t1 = time.perf_counter()
        for m in msgs:
            msgeccs.append(rs.rs_encode_msg(m, 2 * t, gen=gen[2 * t]))
        t2 = time.perf_counter()
        encode_time.write(str(t2 - t1) + '\n')

        # Error
        for msgecc in msgeccs:
            error_inject(msgecc)

        # Decode
        corrections = []
        t1 = time.perf_counter()
        for msgecc in msgeccs:
            corrections.append(rs.rs_correct_msg(msgecc, 2 * t))
        t2 = time.perf_counter()
        decode_time.write(str(t2 - t1) + '\n')

        rmsg = b''
        for c in corrections:
            rmsg += c[0]

        # Check result
        if (msg.decode() == rmsg.decode()):
            print("True")
        else:
            print("False")
Esempio n. 6
0
def decode_im(im):
    print im
    out = bytearray([0] * 24)
    for i in range(0, 24, 3):
        res = 0
        for j in range(8):
            res |= (im[i / 3 * 8 + j] << ((7 - j) * 3))
        out[i] = res >> 16
        out[i + 1] = (res >> 8) & 0xff
        out[i + 2] = res & 0xff

    input = out[:]
    mes, ecc = reedsolo.rs_correct_msg(input, 8)
    err = 0
    for x, y in zip((mes + ecc), input):
        err += sum(map(int, '{:08b}'.format(x ^ y)))
    print "%d errors" % err
    return mes
Esempio n. 7
0
def hread(tout):
    start = time.time()
    while tout <= 0 or (time.time() - start) < tout:
        if ser.inWaiting() >= 3:
            try:
                #sim
                r = ser.read(3)
                if ord(r[0]) > 9:
                    print("Received header: %s\n" % repr(r))
                else:
                    print("Received response: %s\n" % repr(r))
                header = reedsolo.rs_correct_msg(r, 2)[0]

                return ord(header)
            except reedsolo.ReedSolomonError as e:
                return 'Error'

    ser.flushInput
    return None
Esempio n. 8
0
rs.init_tables(c_exp=12, prim=prim)
n = 255
nsym = 12
mes = "a" * (n-nsym)
#mesbytarray=[elem.encode(decimal.Decimal) for elem in mes]
gen = rs.rs_generator_poly_all(n)
print(len(gen))
enc = rs.rs_encode_msg(mes, nsym, gen=gen[nsym])
enc[1] = 0
enc[2]=0
enc[4]=0
enc[8]=0
enc[32] = 0
enc[33]=0

rmes, recc = rs.rs_correct_msg(enc, nsym, erase_pos=None)
# print("msg= ", mes)
# print("enc= ", enc)
# print("dec= ", rmes)

mesbytarray="".join(chr(i) for i in rmes)
#print("mesba= ",mesbytarray)
#print(type(mes),type(mesbytarray))
if mes == mesbytarray:
    print("Sucess")
else:
    print("FAIL")
# i=10
# #rs=RSCodec(nsym=i,c_exp=10)
# rs=RSCodec(i)
# msg=bytearray(randomString(20), "latin1")
Esempio n. 9
0
            # Channel simulation
            for x, y in enumerate(en):
                # Add errors based on probability to be tested
                if random.random() < pe[i]:
                    # Avoid writing a symbol that is the same as the original
                    if en[x] != 1:
                        en[x] = 1
                    else:
                        en[x] = 0

            if en[:-nk] == packet[:-nk]:
                ndec[i] += 1

            # Test if decodable
            try:
                de = reedsolo.rs_correct_msg(en, nk)[0]
                # Correct decoding?
                if de == packet[:-nk]:
                    dec[i] += 1
                else:
                    idec[i] += 1
            except reedsolo.ReedSolomonError:
                continue

    # Get theoretical values
    # Probabilities of decoding
    pt = [PDP(m, l, nk) for y, m in enumerate(pe)]
    # Multiply by packets
    dect = [a * n for y, a in enumerate(pt)] + [0]

    # ndec - Uncoded number
Esempio n. 10
0
                    if en[x] != 1:
                        en[x] = 1
                    else:
                        en[x] = 0

            if len(en) > 2:
                todec = en[:]
            else:
                todec += en[:]

            # Decode
            try:
                #FEC
                rs_packet = todec + ''.join('0' for x in range(18 - nk))
                de = reedsolo.rs_correct_msg(
                    rs_packet, 18, 0, 2,
                    [rs
                     for rs in range(len(todec), (len(todec) + (18 - nk)))])[0]
                # Correct decoding?
                if de == p[:-18]:
                    dec[i] += 1
                else:
                    idec[i] += 1

                break
            except (reedsolo.ReedSolomonError, ZeroDivisionError):
                nsym[i] += 5
                nak_count += 1
                if (nki + nak_count * 2) > 18:
                    terr[i] += 1
                    break
Esempio n. 11
0
        print u'\n総コード語数: {0}'.format(len(blocks))
        print u'データブロック: {0}'.format(repr(blocks))

    reedsolo.init_tables(0x11d)

    # from writeup: https://www.robertxiao.ca/hacking/ctf-writeup/mma2015-qrcode/
    b = bytearray()
    erasures = []
    for i, bits in enumerate(blocks):
        if '?' in bits:
            erasures.append(i)
            b.append(0)
        else:
            b.append(int(bits, 2))

    mes, ecc = reedsolo.rs_correct_msg(b, 22, erase_pos=erasures)
    for i, c in enumerate(mes):
        blocks[i] = '{:08b}'.format(c)

    #RSブロックに分割する
    RS_blocks = []
    block_num = RS_block_num_table[version - 1][error_correction_level]
    offset = data_code_num_table[version - 1][error_correction_level]
    for i in range(block_num):
        t = []
        for j in range(offset // block_num):  #データ部
            t.append(blocks[j * block_num + i])
        if offset % block_num != 0:  #端数のある場合
            remain = offset % block_num
            if (block_num - remain) <= i:
                t.append(blocks[(offset // block_num) * block_num +
Esempio n. 12
0
def error_correction(raw_bit_array, version, ecc_level):
    '''
    Extracts the error-corrected data out of a raw bit array
    Keyword arguments:
    raw_bit_array -- the list of booleans being extracted from the data matrix
    version -- the version of the qr code (1-40)
    ecc_level -- the level of the error correction (0-3)
    Returns:
    A list of booleans, which have been corrected with the error-correction algorithm 
        (This will contain less elements than the raw_bit_array)
    '''

    CODEWORD_COUNT_LOOKUP = [[19, 16, 13, 9], [34, 28, 22, 16],
                             [55, 44, 34, 26], [80, 64, 48, 36],
                             [108, 86, 62, 46], [136, 108, 76, 60],
                             [156, 124, 88, 66], [194, 154, 110, 86],
                             [232, 182, 132, 100], [274, 216, 154, 122],
                             [324, 254, 180, 140], [370, 290, 206, 158],
                             [428, 334, 244, 180], [461, 365, 261, 197],
                             [523, 415, 295, 223], [589, 453, 325, 253],
                             [647, 507, 367, 283], [721, 563, 397, 313],
                             [795, 627, 445, 341], [861, 669, 485, 385],
                             [932, 714, 512, 406], [1006, 782, 568, 442],
                             [1094, 860, 614, 464], [1174, 914, 664, 514],
                             [1276, 1000, 718, 538], [1370, 1062, 754, 596],
                             [1468, 1128, 808, 628], [1531, 1193, 871, 661],
                             [1631, 1267, 911, 701], [1735, 1373, 985, 745],
                             [1843, 1455, 1033, 793], [1955, 1541, 1115, 845],
                             [2071, 1631, 1171, 901], [2191, 1725, 1231, 961],
                             [2306, 1812, 1286, 986], [2434, 1914, 1354, 1054],
                             [2566, 1992, 1426,
                              1096], [2702, 2102, 1502, 1142],
                             [2812, 2216, 1582,
                              1222], [2956, 2334, 1666, 1276]]

    BLOCK_COUNT_LOOKUP = [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 2,
                                                       2], [1, 2, 2, 4],
                          [1, 2, 4, 4], [2, 4, 4, 4], [2, 4, 6, 5],
                          [2, 4, 6, 6], [2, 5, 8, 8], [4, 5, 8, 8],
                          [4, 5, 8, 11], [4, 8, 10, 11], [4, 9, 12, 16],
                          [4, 9, 16, 16], [6, 10, 12, 18], [6, 10, 17, 16],
                          [6, 11, 16, 19], [6, 13, 18, 21], [7, 14, 21, 25],
                          [8, 16, 20, 25], [8, 17, 23, 25], [9, 17, 23, 34],
                          [9, 18, 25, 30], [10, 20, 27, 32], [12, 21, 29, 35],
                          [12, 23, 34, 37], [12, 25, 34, 40], [13, 26, 35, 42],
                          [14, 28, 38, 45], [15, 29, 40, 48], [16, 31, 43, 51],
                          [17, 33, 45, 54], [18, 35, 48, 57], [19, 37, 51, 60],
                          [19, 38, 53, 63], [20, 40, 56, 66], [21, 43, 59, 70],
                          [22, 45, 62, 74], [24, 47, 65, 77], [25, 49, 68, 81]]

    # the amount of blocks being interwoven
    block_count = BLOCK_COUNT_LOOKUP[version - 1][ecc_level]
    # the sum of data bytes without error-correction overhead being contained in all blocks
    codeword_count = CODEWORD_COUNT_LOOKUP[version - 1][ecc_level]

    bytes_count = raw_bit_array.size // 8  # the amount of entire bytes contained in the bit array
    # the amount of data bytes without error-correction overhead contained in a short block
    short_codeword_block_bytes_count = codeword_count // block_count
    #long_codeword_block_bytes_count = short_block_bytes_count + 1
    # not required. The amount of bytes in long blocks is 1 greater than the short blocks

    # the amount of bytes in the error-correction part of each block
    errorcorrection_block_bytes_count = (bytes_count -
                                         codeword_count) // block_count

    # The amount of long data blocks
    long_codeword_block_count = codeword_count % block_count
    # The amount of short data blocks
    short_codeword_block_count = block_count - long_codeword_block_count

    # generators of indices for the data block.
    # The indices of the short blocks are completely regular and always have the
    # distance block_count
    # The indices of the long blocks are regularly exceptional the last index.
    # The last index only has the distance long_codeword_block_count instead of
    # block_count from the next to the last
    # Therefor two different generators are generated and chained
    short_codeword_block_index_list_gen = (range(
        block, short_codeword_block_bytes_count * block_count,
        block_count) for block in range(short_codeword_block_count))

    long_codeword_block_index_list_gen = (itertools.chain(
        range(block, short_codeword_block_bytes_count * block_count,
              block_count),
        [short_codeword_block_bytes_count * block_count + block
         ]) for block in range(short_codeword_block_count, block_count))

    codeword_block_index_list_gen = itertools.chain(
        short_codeword_block_index_list_gen,
        long_codeword_block_index_list_gen)

    # The error-correction blocks are all of the same size, have a regular
    # distance and start after all the data blocks
    errorcorrection_block_index_list_gen = (range(codeword_count + block,
                                                  bytes_count, block_count)
                                            for block in range(block_count))

    # extracting the data and the correction data for each block
    codeword_errorcorrection_block_index_list_gen = (list(
        itertools.chain(block,
                        correction_data)) for block, correction_data in zip(
                            codeword_block_index_list_gen,
                            errorcorrection_block_index_list_gen))

    raw_byte_array = np.packbits(
        raw_bit_array)  # converting the array of bits to arrays of bytes

    # applying reed Solomon error-correction to all blocks
    # the result is a generator of np arrays of corrected bytes
    corrected_byte_list_gen = (reedsolo.rs_correct_msg(
        raw_byte_array[codeword_errorcorrection_block_index_list],
        errorcorrection_block_bytes_count)
                               for codeword_errorcorrection_block_index_list in
                               codeword_errorcorrection_block_index_list_gen)

    # concatenating the bytes of each block to one array
    corrected_byte_array = np.fromiter(
        itertools.chain.from_iterable(corrected_byte_list_gen),
        dtype=np.uint8,
        count=codeword_count)

    # extracting the bits from the bytes
    corrected_bit_array = np.unpackbits(corrected_byte_array)

    return corrected_bit_array
Esempio n. 13
0
def get_data(header):
    seq_last = int(100)  # Random number different from 1
    buffer = []
    retr_seq = 0  # Retransmission sequence

    while True:
        if header == 'Error':
            ser.flushInput()
            ser.write(nak_pack)
            header = hread(TOUT_recv)
            continue
        elif 6 < header < 9:
            # It is an ACK or a NAK
            print("In function get_data: Expected data, ARQ response found")
            logging.critical(
                "In function get_data: Expected data, ARQ response found")
            return None
        else:
            break

    while True:
        temp = pread(header)
        if temp == None:
            print("In function get_data: Expected packet")
            logging.critical("In function get_data: Expected packet")
            return None

        # Check if it's a retransmission
        if 2 <= header <= 3:
            # It's a retransmission
            if retr_seq != header:  # Append the FEC symbols only if the sequence is different from the last one
                packet += temp
                header = len(packet)
        else:
            packet = temp

        # Calculate N-K based on packet length
        if header >= 237:  # 236+1 packet
            dlength = 237
        elif 65 <= header < 237:  # 64+1 packet
            dlength = 65
        else:  # 8+1 packet
            dlength = 9

        nk = header - dlength

        # header = data + current FEC
        # dlength = data
        # nk = FEC
        # dlength + 18 = max packet
        try:
            # Parse sequence number and data
            if nk > 0:
                rs_packet = packet + ''.join('0' for x in range(18 - nk))
                p = reedsolo.rs_correct_msg(
                    rs_packet, 18, 0, 2,
                    [i for i in range(header, (dlength + 18))])[0]
                seq = p[0]
                data = p[1:]
            else:
                seq = ord(packet[0])
                data = packet[1:]

            if seq != seq_last:
                # Remove zeros padded for last packet
                if 0 < seq <= 7:
                    data = data[:-seq]

                buffer.append(data.decode('utf-8'))
                seq_last = seq

            if seq <= 7:
                return b"".join(buffer)

            # Reset retransmission sequence
            retr_seq = 0
            # Send ACK
            ser.write(ack_pack)

        except (reedsolo.ReedSolomonError, ZeroDivisionError):
            # Send NAK
            ser.write(nak_pack)

            if nk == 18:  # Maximum FEC bytes reached
                print("In function get_data: Maximum NAK reached")
                logging.critical("In function get_data: Maximum NAK reached")
                terminator(
                    0
                )  # Respond to communication attempts by sending out a NAK
                return None

        # Read header
        while True:
            header = hread(TOUT_recv)

            if header == None:
                print("In function get_data: Connection timed out")
                logging.critical("In function get_data: Connection timed out")
                return None
            elif header == 'Error':
                ser.flushInput()
                ser.write(nak_pack)
                continue
            elif 6 < header < 9:
                # It is an ACK or a NAK
                print(
                    "In function get_data: Expected data, ARQ response found")
                logging.critical(
                    "In function get_data: Expected data, ARQ response found")
                return None
            else:
                break
Esempio n. 14
0
11000011
10000000
10101100
00010000
11100100
10101010
10011001
01100110
????????
????????
?????0?0
00000000
????????
????????
????????
????????
????????'''.split()

b = bytearray()
erasures = []
for i, bits in enumerate(qr_bytes):
    if '?' in bits:
        erasures.append(i)
        b.append(0)
    else:
        b.append(int(bits, 2))

mes, ecc = reedsolo.rs_correct_msg(b, 22, erase_pos=erasures)
for c in mes:
    print '{:08b}'.format(c)