tomerfiliba-org / reedsolomon

⏳🛡 Pythonic universal errors-and-erasures Reed-Solomon codec to protect your data from errors and bitrot. Includes a future-proof zero-dependencies pure-python implementation 🔮 and an optional speed-optimized Cython/C extension 🚀
http://pypi.python.org/pypi/reedsolo
Other
358 stars 86 forks source link

rs_calc_syndromes could not find injected error #68

Closed ykc21e8 closed 1 year ago

ykc21e8 commented 1 year ago

I'm not sure if it's just me.

But I first found this issue with the wikiversity article, so I thought the python reed-solo wouldn't have this issue, but I'm encountering the same issue.


msg_in = [ 0x40, 0xd2, 0x75, 0x47, 0x76, 0x17, 0x32, 0x06, 0x27, 0x26, 0x96, 0xc6, 0xc6, 0x96, 0x70, 0xec ]
msg = rs_encode_msg(msg_in, 10)

synd = rs_calc_syndromes(msg, 10)
print("Message initial: ")
for i in range(0,len(msg)):
    print(hex(msg[i]), end=' ')
print(synd) # not corrupted message = all 0 syndromes
msg[0] = 0  # deliberately damage the message
synd = rs_calc_syndromes(msg, 10)
print("Message after: ")
for i in range(0,len(msg)):
    print(hex(msg[i]), end=' ')
print(synd) # when corrupted, the syndromes will be non zero

synd = rs_calc_syndromes(msg, 10)
msg = rs_correct_errata(msg, synd, [0]) # [0] is the list of the erasures locations, here it's the first character, at position 0
print(hex(msg[0]))

image

After injecting error by changing the first bit of the message into zero, I recalculate the syndromes, but the resulting syndrome is exactly the same! Meaning rs_correct_errata makes no correction.

Could someone let me know whether I'm just not understanding.

lrq3000 commented 1 year ago

Hello, it seems you forgot to initialize the tables, so that’s why you always get an empty syndromes, the codec is not working at all. Here is the same snippet but working as intended:

from reedsolo import *

init_tables(0x11d)

msg_in = [ 0x40, 0xd2, 0x75, 0x47, 0x76, 0x17, 0x32, 0x06, 0x27, 0x26, 0x96, 0xc6, 0xc6, 0x96, 0x70, 0xec ]
msg = rs_encode_msg(msg_in, 10)

synd = rs_calc_syndromes(msg, 10)
print("Message initial: ")
for i in range(0,len(msg)):
    print(hex(msg[i]), end=' ')
print("\nSyndrome:" + str(synd)) # not corrupted message = all 0 syndromes

msg[0] = 0  # deliberately damage the message
synd = rs_calc_syndromes(msg, 10)
print("Message after: ")
for i in range(0,len(msg)):
    print(hex(msg[i]), end=' ')
print("\nSyndrome:" + str(synd)) # when corrupted, the syndromes will be non zero

synd = rs_calc_syndromes(msg, 10)
msg = rs_correct_errata(msg, synd, [0]) # [0] is the list of the erasures locations, here it's the first character, at position 0
print(hex(msg[0]))

Anyway, even if the above works, it uses the low-level functions directly, but if you are new to reed-solomon codecs, I would strongly recommend to rather use the high-level RSCodec class, it automatically manages these things in the background so you don’t have to.