Esempio n. 1
0
 def test_prim_fcr_long(self):
     nn = 48
     kk = 34
     tt = nn - kk
     rs = RSCodec(tt, fcr=120, prim=0x187)
     hexencmsg = '08faa123555555c000000354064432c0280e1b4d090cfc04887400' \
         '000003500000000e1985ff9c6b33066ca9f43d12e8'
     strf = str if sys.version_info[0] >= 3 else unicode    
     encmsg = bytearray.fromhex(strf(hexencmsg))
     decmsg = encmsg[:kk]
     tem = rs.encode(decmsg)
     self.assertEqual(encmsg, tem, msg="encoded does not match expected")
     tdm, _, _ = rs.decode(tem)
     self.assertEqual(tdm, decmsg, 
         msg="decoded does not match original")
     tem1 = bytearray(tem)
     numerrs = tt >> 1
     for i in sample(range(nn), numerrs):
         tem1[i] ^= 0xff
     tdm, _, _ = rs.decode(tem1)
     self.assertEqual(tdm, decmsg,
         msg="decoded with errors does not match original")
     tem1 = bytearray(tem)
     numerrs += 1
     for i in sample(range(nn), numerrs):
         tem1[i] ^= 0xff
     self.assertRaises(ReedSolomonError, rs.decode, tem1)
Esempio n. 2
0
 def test_prim_fcr_basic(self):
     nn = 30
     kk = 18
     tt = nn - kk
     rs = RSCodec(tt, fcr=120, prim=0x187)
     hexencmsg = '00faa123555555c000000354064432c02800fe97c434e1ff5365' \
         'cf8fafe4'
     strf = str if sys.version_info[0] >= 3 else unicode    
     encmsg = bytearray.fromhex(strf(hexencmsg))
     decmsg = encmsg[:kk]
     tem = rs.encode(decmsg)
     self.assertEqual(encmsg, tem, msg="encoded does not match expected")
     tdm = rs.decode(tem)
     self.assertEqual(tdm, decmsg, msg="decoded does not match original")
     tem1 = bytearray(tem) # clone a copy
     # encoding and decoding intact message seem OK, so test errors
     numerrs = tt >> 1 # inject tt/2 errors (expected to recover fully)
     for i in sample(range(nn), numerrs): # inject errors in random places
         tem1[i] ^= 0xff # flip all 8 bits
     tdm = rs.decode(tem1)
     self.assertEqual(tdm, decmsg,
         msg="decoded with errors does not match original")
     tem1 = bytearray(tem) # clone another copy
     numerrs += 1 # inject tt/2 + 1 errors (expected to fail and detect it)
     for i in sample(range(nn), numerrs): # inject errors in random places
         tem1[i] ^= 0xff # flip all 8 bits
     # if this fails, it means excessive errors not detected
     self.assertRaises(ReedSolomonError, rs.decode, tem1)
Esempio n. 3
0
 def test_prim_fcr_basic(self):
     nn = 30
     kk = 18
     tt = nn - kk
     rs = RSCodec(tt, fcr=120, prim=0x187)
     hexencmsg = '00faa123555555c000000354064432c02800fe97c434e1ff5365' \
         'cf8fafe4'
     strf = str if sys.version_info[0] >= 3 else unicode    
     encmsg = bytearray.fromhex(strf(hexencmsg))
     decmsg = encmsg[:kk]
     tem = rs.encode(decmsg)
     self.assertEqual(encmsg, tem, msg="encoded does not match expected")
     tdm, _, _ = rs.decode(tem)
     self.assertEqual(tdm, decmsg, msg="decoded does not match original")
     tem1 = bytearray(tem) # clone a copy
     # encoding and decoding intact message seem OK, so test errors
     numerrs = tt >> 1 # inject tt/2 errors (expected to recover fully)
     for i in sample(range(nn), numerrs): # inject errors in random places
         tem1[i] ^= 0xff # flip all 8 bits
     tdm, _, _ = rs.decode(tem1)
     self.assertEqual(tdm, decmsg,
         msg="decoded with errors does not match original")
     tem1 = bytearray(tem) # clone another copy
     numerrs += 1 # inject tt/2 + 1 errors (expected to fail and detect it)
     for i in sample(range(nn), numerrs): # inject errors in random places
         tem1[i] ^= 0xff # flip all 8 bits
     # if this fails, it means excessive errors not detected
     self.assertRaises(ReedSolomonError, rs.decode, tem1)
Esempio n. 4
0
 def test_prim_fcr_long(self):
     nn = 48
     kk = 34
     tt = nn - kk
     rs = RSCodec(tt, fcr=120, prim=0x187)
     hexencmsg = '08faa123555555c000000354064432c0280e1b4d090cfc04887400' \
         '000003500000000e1985ff9c6b33066ca9f43d12e8'
     strf = str if sys.version_info[0] >= 3 else unicode    
     encmsg = bytearray.fromhex(strf(hexencmsg))
     decmsg = encmsg[:kk]
     tem = rs.encode(decmsg)
     self.assertEqual(encmsg, tem, msg="encoded does not match expected")
     tdm = rs.decode(tem)
     self.assertEqual(tdm, decmsg, 
         msg="decoded does not match original")
     tem1 = bytearray(tem)
     numerrs = tt >> 1
     for i in sample(range(nn), numerrs):
         tem1[i] ^= 0xff
     tdm = rs.decode(tem1)
     self.assertEqual(tdm, decmsg,
         msg="decoded with errors does not match original")
     tem1 = bytearray(tem)
     numerrs += 1
     for i in sample(range(nn), numerrs):
         tem1[i] ^= 0xff
     self.assertRaises(ReedSolomonError, rs.decode, tem1)
Esempio n. 5
0
 def test_long(self):
     rs = RSCodec(10)
     msg = bytearray("a" * 10000, "latin1")
     enc = rs.encode(msg)
     dec, _, _ = rs.decode(enc)
     self.assertEqual(dec, msg)
     enc[177] = 99
     enc[2212] = 88
     dec2, _, _ = rs.decode(enc)
     self.assertEqual(dec2, msg)
Esempio n. 6
0
 def test_long(self):
     rs = RSCodec(10)
     msg = bytearray("a" * 10000, "latin1")
     enc = rs.encode(msg)
     dec = rs.decode(enc)
     self.assertEqual(dec, msg)
     enc[177] = 99
     enc[2212] = 88
     dec2 = rs.decode(enc)
     self.assertEqual(dec2, msg)
Esempio n. 7
0
 def test_correction(self):
     rs = RSCodec(10)
     msg = bytearray("hello world " * 10, "latin1")
     enc = rs.encode(msg)
     self.assertEqual(rs.decode(enc), msg)
     for i in [27, -3, -9, 7, 0]:
         enc[i] = 99
         self.assertEqual(rs.decode(enc), msg)
     enc[82] = 99
     self.assertRaises(ReedSolomonError, rs.decode, enc)
Esempio n. 8
0
 def test_simple(self):
     rs = RSCodec(10)
     msg = bytearray("hello world " * 10, "latin1")
     enc = rs.encode(msg)
     dec, dec_enc, errata_pos = rs.decode(enc)
     self.assertEqual(dec, msg)
Esempio n. 9
0
        def test_main(self):
            def cartesian_product_dict_items(dicts):
                return (dict(izip(dicts, x)) for x in itertools.product(*dicts.values()))

            debugg = False # if one or more tests don't pass, you can enable this flag to True to get verbose output to debug

            orig_mes = bytearray("hello world", "latin1")
            n = len(orig_mes)*2
            k = len(orig_mes)
            nsym = n-k
            istart = 0

            params = {"count": 5,
                      "fcr": [120, 0, 1, 1, 1],
                      "prim": [0x187, 0x11d, 0x11b, 0xfd, 0xfd],
                      "generator": [2, 2, 3, 3, 2],
                      "c_exponent": [8, 8, 8, 7, 7],
                     }
            cases = {
                     "errmode": [1, 2, 3, 4],
                     "erratasnb_errorsnb_onlyeras": [[8, 3, False], [6, 5, False], [5, 5, False], [11, 0, True], [11, 0, False], [0,0, False]], # errata number (errors+erasures), erasures number and only_erasures: the last item is the value for only_erasures (True/False)
                     }

            ############################$

            results_br = []
            results_rs = []

            it = 0
            for p in xrange(params["count"]):
                fcr = params["fcr"][p]
                prim = params["prim"][p]
                generator = params["generator"][p]
                c_exponent = params["c_exponent"][p]

                for case in cartesian_product_dict_items(cases):
                    errmode = case["errmode"]
                    erratanb = case["erratasnb_errorsnb_onlyeras"][0]
                    errnb = case["erratasnb_errorsnb_onlyeras"][1]
                    only_erasures = case["erratasnb_errorsnb_onlyeras"][2]
                    
                    it += 1
                    if debugg:
                        print("it ", it)
                        print("param", p)
                        print(case)

                    # REEDSOLO
                    # Init the RS codec
                    init_tables(generator=generator, prim=prim, c_exp=c_exponent)
                    g = rs_generator_poly_all(n, fcr=fcr, generator=generator)
                    # Encode the message
                    rmesecc = rs_encode_msg(orig_mes, n-k, gen=g[n-k])
                    rmesecc_orig = rmesecc[:] # make a copy of the original message to check later if fully corrected (because the syndrome may be wrong sometimes)
                    # Tamper the message
                    if erratanb > 0:
                        if errmode == 1:
                            sl = slice(istart, istart+erratanb)
                        elif errmode == 2:
                            sl = slice(-istart-erratanb-(n-k), -(n-k))
                        elif errmode == 3:
                            sl = slice(-istart-erratanb-1, -1)
                        elif errmode == 4:
                            sl = slice(-istart-erratanb, None)
                        if debugg:
                            print("Removed slice:", list(rmesecc[sl]), rmesecc[sl])
                        rmesecc[sl] = [0] * erratanb
                    # Generate the erasures positions (if any)
                    erase_pos = [x for x in xrange(len(rmesecc)) if rmesecc[x] == 0]
                    if errnb > 0: erase_pos = erase_pos[:-errnb] # remove the errors positions (must not be known by definition)
                    if debugg:
                        print("erase_pos", erase_pos)
                        print("coef_pos", [len(rmesecc) - 1 - pos for pos in erase_pos])
                        print("Errata total: ", erratanb-errnb + errnb*2, " -- Correctable? ", (erratanb-errnb + errnb*2 <= nsym))
                    # Decoding the corrupted codeword
                    # -- Forney syndrome method
                    try:
                        rmes, recc, errata_pos = rs_correct_msg(rmesecc, n-k, fcr=fcr, generator=generator, erase_pos=erase_pos, only_erasures=only_erasures)
                        results_br.append( rs_check(rmes + recc, n-k, fcr=fcr, generator=generator) ) # check if correct by syndrome analysis (can be wrong)
                        results_br.append( rmesecc_orig == (rmes+recc) ) # check if correct by comparing to the original message (always correct)
                        if debugg and not rs_check(rmes + recc, n-k, fcr=fcr, generator=generator) or not (rmesecc_orig == (rmes+recc)): raise ReedSolomonError("False!!!!!")
                    except ReedSolomonError as exc:
                        results_br.append(False)
                        results_br.append(False)
                        if debugg:
                            print("====")
                            print("ERROR! Details:")
                            print("param", p)
                            print(case)
                            print(erase_pos)
                            print("original_msg", rmesecc_orig)
                            print("tampered_msg", rmesecc)
                            print("decoded_msg", rmes+recc)
                            print("checks: ", rs_check(rmes + recc, n-k, fcr=fcr, generator=generator), rmesecc_orig == (rmes+recc))
                            print("====")
                            raise exc
                    # -- Without Forney syndrome method
                    try:
                        mes, ecc, errata_pos = rs_correct_msg_nofsynd(rmesecc, n-k, fcr=fcr, generator=generator, erase_pos=erase_pos, only_erasures=only_erasures)
                        results_br.append( rs_check(rmes + recc, n-k, fcr=fcr, generator=generator) )
                        results_br.append( rmesecc_orig == (rmes+recc) )
                    except ReedSolomonError as exc:
                        results_br.append(False)
                        results_br.append(False)

                    if debugg: print("-----")

            self.assertTrue(results_br.count(True) == len(results_br))
Esempio n. 10
0
 def test_simple(self):
     rs = RSCodec(10)
     msg = bytearray("hello world " * 10, "latin1")
     enc = rs.encode(msg)
     dec = rs.decode(enc)
     self.assertEqual(dec, msg)
Esempio n. 11
0
        def test_main(self):
            def cartesian_product_dict_items(dicts):
                return (dict(izip(dicts, x)) for x in itertools.product(*dicts.values()))

            debugg = False # if one or more tests don't pass, you can enable this flag to True to get verbose output to debug

            orig_mes = bytearray("hello world", "latin1")
            n = len(orig_mes)*2
            k = len(orig_mes)
            nsym = n-k
            istart = 0

            params = {"count": 5,
                      "fcr": [120, 0, 1, 1, 1],
                      "prim": [0x187, 0x11d, 0x11b, 0xfd, 0xfd],
                      "generator": [2, 2, 3, 3, 2],
                      "c_exponent": [8, 8, 8, 7, 7],
                     }
            cases = {
                     "errmode": [1, 2, 3, 4],
                     "erratasnb_errorsnb_onlyeras": [[8, 3, False], [6, 5, False], [5, 5, False], [11, 0, True], [11, 0, False], [0,0, False]], # errata number (errors+erasures), erasures number and only_erasures: the last item is the value for only_erasures (True/False)
                     }

            ############################$

            results_br = []
            results_rs = []

            it = 0
            for p in xrange(params["count"]):
                fcr = params["fcr"][p]
                prim = params["prim"][p]
                generator = params["generator"][p]
                c_exponent = params["c_exponent"][p]

                for case in cartesian_product_dict_items(cases):
                    errmode = case["errmode"]
                    erratanb = case["erratasnb_errorsnb_onlyeras"][0]
                    errnb = case["erratasnb_errorsnb_onlyeras"][1]
                    only_erasures = case["erratasnb_errorsnb_onlyeras"][2]
                    
                    it += 1
                    if debugg:
                        print("it ", it)
                        print("param", p)
                        print(case)

                    # REEDSOLO
                    # Init the RS codec
                    init_tables(generator=generator, prim=prim, c_exp=c_exponent)
                    g = rs_generator_poly_all(n, fcr=fcr, generator=generator)
                    # Encode the message
                    rmesecc = rs_encode_msg(orig_mes, n-k, gen=g[n-k])
                    rmesecc_orig = rmesecc[:] # make a copy of the original message to check later if fully corrected (because the syndrome may be wrong sometimes)
                    # Tamper the message
                    if erratanb > 0:
                        if errmode == 1:
                            sl = slice(istart, istart+erratanb)
                        elif errmode == 2:
                            sl = slice(-istart-erratanb-(n-k), -(n-k))
                        elif errmode == 3:
                            sl = slice(-istart-erratanb-1, -1)
                        elif errmode == 4:
                            sl = slice(-istart-erratanb, None)
                        if debugg:
                            print("Removed slice:", list(rmesecc[sl]), rmesecc[sl])
                        rmesecc[sl] = [0] * erratanb
                    # Generate the erasures positions (if any)
                    erase_pos = [x for x in xrange(len(rmesecc)) if rmesecc[x] == 0]
                    if errnb > 0: erase_pos = erase_pos[:-errnb] # remove the errors positions (must not be known by definition)
                    if debugg:
                        print("erase_pos", erase_pos)
                        print("coef_pos", [len(rmesecc) - 1 - pos for pos in erase_pos])
                        print("Errata total: ", erratanb-errnb + errnb*2, " -- Correctable? ", (erratanb-errnb + errnb*2 <= nsym))
                    # Decoding the corrupted codeword
                    # -- Forney syndrome method
                    try:
                        rmes, recc = rs_correct_msg(rmesecc, n-k, fcr=fcr, generator=generator, erase_pos=erase_pos, only_erasures=only_erasures)
                        results_br.append( rs_check(rmes + recc, n-k, fcr=fcr, generator=generator) ) # check if correct by syndrome analysis (can be wrong)
                        results_br.append( rmesecc_orig == (rmes+recc) ) # check if correct by comparing to the original message (always correct)
                        if debugg and not rs_check(rmes + recc, n-k, fcr=fcr, generator=generator) or not (rmesecc_orig == (rmes+recc)): raise ReedSolomonError("False!!!!!")
                    except ReedSolomonError as exc:
                        results_br.append(False)
                        results_br.append(False)
                        if debugg:
                            print("====")
                            print("ERROR! Details:")
                            print("param", p)
                            print(case)
                            print(erase_pos)
                            print("original_msg", rmesecc_orig)
                            print("tampered_msg", rmesecc)
                            print("decoded_msg", rmes+recc)
                            print("checks: ", rs_check(rmes + recc, n-k, fcr=fcr, generator=generator), rmesecc_orig == (rmes+recc))
                            print("====")
                            raise exc
                    # -- Without Forney syndrome method
                    try:
                        mes, ecc = rs_correct_msg_nofsynd(rmesecc, n-k, fcr=fcr, generator=generator, erase_pos=erase_pos, only_erasures=only_erasures)
                        results_br.append( rs_check(rmes + recc, n-k, fcr=fcr, generator=generator) )
                        results_br.append( rmesecc_orig == (rmes+recc) )
                    except ReedSolomonError as exc:
                        results_br.append(False)
                        results_br.append(False)

                    if debugg: print("-----")

            self.assertTrue(results_br.count(True) == len(results_br))