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