def encode(input, output_filename): """Encodes the input data with reed-solomon error correction in 223 byte blocks, and outputs each block along with 32 parity bytes to a new file by the given filename. input is a file-like object The outputted image will be in png format, and will be 255 by x pixels with one color channel. X is the number of 255 byte blocks from the input. Each block of data will be one row, therefore, the data can be recovered if no more than 16 pixels per row are altered. """ coder = rs.RSCoder(255, 223) output = [] while True: block = input.read(223) if not block: break code = coder.encode_fast(block) output.append(code) sys.stderr.write(".") sys.stderr.write("\n") out = Image.new("L", (rowstride, len(output))) out.putdata("".join(output)) out.save(output_filename)
def rs_encode_image(image_file, code_word_num): with open(image_file, 'rb') as f: image_contain = f.read() k = ceil(len(image_contain) / float(PACKET_SIZE)) n = 2**ceil(log(k) / log(2)) fout = open(IMAGE + '.rs', 'wb') mat = [] for i in range(k): if (len(image_contain) > (i + 1) * PACKET_SIZE): mat.append([ str(ii) for ii in list(image_contain[i * PACKET_SIZE:(i + 1) * PACKET_SIZE]) ]) else: empty = ['0' for ii in range(PACKET_SIZE)] empty[:(len(image_contain) - i * PACKET_SIZE)] = list( image_contain[i * PACKET_SIZE:len(image_contain)]) mat.append(empty) for i in range(n - k): mat.append(['0' for ii in range(PACKET_SIZE)]) mat_arr_orig = np.array(mat) mat_arr_code = mat_arr_orig coder = rs.RSCoder(n, k) for i in range(PACKET_SIZE): code_word = list( coder.encode(bytes([int(ii) for ii in mat_arr_orig[:k, i]]))) mat_arr_code[:, i] = code_word for line in mat_arr_code: fout.write(bytes(''.join(list(line)), encoding='utf-8')) fout.close() return mat_arr_orig, image_contain, mat, mat_arr_code
def decode(input_filename): coder = rs.RSCoder(255, 223) input = Image.open(input_filename) data = "".join(chr(x) for x in input.getdata()) del input blocknum = 0 while True: if blocknum * 255 > len(data): break rowdata = data[blocknum * 255:(blocknum + 1) * 255] if not rowdata: break decoded = coder.decode_fast(rowdata) blocknum += 1 sys.stdout.write(str(decoded)) sys.stderr.write(".") sys.stderr.write("\n")
def computeId(ids, erasure): def fromStr(a): return [ord(x) for x in a] def toStr(a): return ''.join([str(chr(x)) for x in a]) # Compared to libfec: # (python) generator 3 maps to prim 13 in libfec # (python) fcr 1 maps to fcr 19 in libfec # found after exhaustive search... # # The rest is similar: gfpoly=0x25, symbolsize=2^5, 20 symbols per block, # i.e., 12 parity and 8 data (encoding a 40bit id). coder = rs.RSCoder(20, 8, 3, 0x25, 1, 5) print 'Number of erasures: {0}'.format(len(erasure)) try: corrected, ecc = coder.decode(toStr(ids), k=8, nostrip=True, erasures_pos=erasure) ecc = fromStr(ecc) corrected = fromStr(corrected) print corrected, ecc all = corrected + ecc if not coder.check(toStr(all)): print 'Cannot validate ecc' return None else: result = 0 for i, x in enumerate(corrected): result = result + x if i < len(corrected) - 1: result = result * 32 # 2^5 return result except Exception as inst: print 'Cannot recover id: ', inst return None
#uint32 omzetten naar uint8 encoded_msg_bit = util.uint32_to_bit(encoded_msg) encoded_msg_8uint = util.bit_to_uint8(encoded_msg_bit) uint8_stream = np.array(encoded_msg, dtype=np.uint8) # ====================== CHANNEL ENCODING ======================== # ======================== Reed-Solomon ========================== print("-------START CHANNEL ENCODING-------") initiele_lengte = len(uint8_stream) print("ingang channel encoder:", uint8_stream) # as we are working with symbols of 8 bits # choose n such that m is divisable by 8 when n=2^m−1 # Example: 255 + 1 = 2^m -> m = 8 n = 255 # code_word_length in symbols k = 223 # message_length in symbols coder = rs.RSCoder(n, k) # generate a matrix with k rows (for each message) uint8_stream.resize((math.ceil(len(uint8_stream) / k), k), refcheck=False) # afterwards you can iterate over each row to encode the message messages = uint8_stream rs_encoded_message = StringIO() for message in messages: code = coder.encode_fast(message, return_string=True) rs_encoded_message.write(code) # TODO What is the RSCoder outputting? Convert to a uint8 (byte) stream before putting it over the channel rs_encoded_message_uint8 = np.array( [ord(c) for c in rs_encoded_message.getvalue()], dtype=np.uint8)
def rs_decode_image(rs_data): # with open(rs_file, 'rb') as f: # rs_contain = f.read() n, k, s, rs_contain = n_k_s_from_image(rs_data) packet_size = int(s) # out_file_name = os.path.basename(rs_data) # out_file_dir = os.path.dirname(rs_data) # out_name = os.path.join(out_file_dir, out_file_name[:-3].replace(".jpg", "_re.jpg")) # fout = open(out_name, 'wb') # print("re image save : {}".format(out_name)) mat = [] for i in range(n): if(len(rs_contain) >= (i+1) * packet_size): if six.PY3: mat_temp = list(rs_contain[i * packet_size: (i+1) * packet_size]) else: mat_temp = [ord(ii) for ii in list(rs_contain[i * packet_size: (i+1) * packet_size])] mat.append(mat_temp) else: empty = [0 for ii in range(packet_size)] if len(rs_contain) > (i+1) * packet_size: if six.PY3: empty[:(len(rs_contain) - i * packet_size)] = \ list(rs_contain[i * packet_size: len(rs_contain)]) else: empty[:(len(rs_contain) - i * packet_size)] = \ [ord(ii) for ii in list(rs_contain[i * packet_size: len(rs_contain)])] mat.append(empty) mat_arr_code = np.array(mat) mat_arr_orig = mat_arr_code[:k, :] coder = rs.RSCoder(n, k) for i in range(packet_size): code_word = b''.join(struct.pack("B", ii) for ii in mat_arr_code[:, i]) # bytes source = coder.decode(code_word)[0] # list str source = [ii for ii in source] if len(source) < k: mat_arr_orig[0:(k-len(source)), i] = [0 for ii in range(k-len(source))] mat_arr_orig[(k-len(source)):, i] = [ord(ii) for ii in source] else: mat_arr_orig[:, i] = [ord(ii) for ii in source] out_image_contain = b'' # out_bytes = b''.join([struct.pack("B", ii) for ii in mat_arr_orig[0, 4:]]) # fout.write(out_bytes) # for line in mat_arr_orig[1:, :]: for line in mat_arr_orig[:, :]: out_bytes = b''.join([struct.pack("B", ii) for ii in list(line)]) out_image_contain += out_bytes print('RS decode done!') # fout.write(out_bytes) # fout.close() # pic = plt.imread(out_name) # plt.imshow(pic) # plt.axis('off') # plt.show() return out_image_contain
def rs_encode_image(image_data, packet_size): ''' 读取文件,按 packet_size大小划分为待编码块 按行排列, 按纵向进行RS编码,增加冗余的编码数据块 packet_size ------------------------------------------- | | 图像文件 | RS ------------------------------------------- | | 图像文件 | ------------------------------------------- 编 | | 图像文件 | ------------------------------------------- | | 图像文件 | 码 ------------------------------------------- | | 图像文件 | ------------------------------------------- 块 |*|**************冗余编码*****************| ------------------------------------------- |*|**************冗余编码*****************| ------------------------------------------- ''' n, k, s, image_contain = n_k_s_to_image(image_data, packet_size) # with open(image_file, 'rb') as f: # image_contain = f.read() #k = 9 #n = 16 print(k, n) # output_rs_file = image_file + '.rs' # fout = open(output_rs_file, 'wb') mat = [] for i in range(k): if(len(image_contain) > (i+1) * packet_size): if six.PY3: mat_temp = list(image_contain[i * packet_size: (i+1) * packet_size]) else: mat_temp = [ord(ii) for ii in list(image_contain[i * packet_size: (i+1) * packet_size])] mat.append(mat_temp) else: # 处理最后一个packet empty = [0 for ii in range(packet_size)] if six.PY3: empty[:(len(image_contain) - i * packet_size)] = \ list(image_contain[i * packet_size: len(image_contain)]) else: empty[:(len(image_contain) - i * packet_size)] = \ [ord(ii) for ii in list(image_contain[i * packet_size: len(image_contain)])] mat.append(empty) # mat[] = [, , , , ] for i in range(n-k): mat.append([0 for ii in range(packet_size)]) mat_arr_orig = np.array(mat) mat_arr_code = mat_arr_orig coder = rs.RSCoder(n, k) for i in range(packet_size): # source = bytes([int(ii) for ii in mat_arr_orig[:k, i]]) source = ''.join([chr(ii) for ii in mat_arr_orig[:k, i]]) # str code_word = list(coder.encode(source)) # string list mat_arr_code[:, i] = [ord(ii) for ii in code_word] # 按列进行编码 out_image_contain = b'' for line in mat_arr_code: # 按行输出 if six.PY3: # print(list(line)) out_bytes = b''.join([struct.pack("B", ii) for ii in list(line)]) elif six.PY2: # print(list(line)) out_bytes = b''.join([struct.pack("B", int(ii)) for ii in list(line)]) out_image_contain += out_bytes # fout.write(out_bytes) # fout.close() return out_image_contain
def rs_decode_image(rs_file, recv_packet): # with open(rs_file, 'rb') as f: # rs_contain = f.read() n, k, s, rs_contain = n_k_s_from_image(rs_file) errpos = count_errpos(recv_packet, n) print("errpos is : {}".format(errpos)) packet_size = int(s) out_file_name = os.path.basename(rs_file) out_file_dir = os.path.dirname(rs_file) out_name = os.path.join(out_file_dir, out_file_name[:-3].replace(".jpg", "_re.jpg")) fout = open(out_name, 'wb') print("re image save : {}".format(out_name)) mat = [] for i in range(n): if (len(rs_contain) >= (i + 1) * packet_size): if six.PY3: mat_temp = list(rs_contain[i * packet_size:(i + 1) * packet_size]) else: mat_temp = [ ord(ii) for ii in list(rs_contain[i * packet_size:(i + 1) * packet_size]) ] mat.append(mat_temp) else: empty = [0 for ii in range(packet_size)] if len(rs_contain) > i * packet_size: if six.PY3: empty[:(len(rs_contain) - i * packet_size)] = \ list(rs_contain[i * packet_size: len(rs_contain)]) else: empty[:(len(rs_contain) - i * packet_size)] = \ [ord(ii) for ii in list(rs_contain[i * packet_size: len(rs_contain)])] mat.append(empty) mat_arr_code = np.array(mat) mat_arr_orig = mat_arr_code[:k, :] print("mat code is:") print(mat_arr_code) print("size of mat code is:") print(mat_arr_code.shape) coder = rs.RSCoder(n, k) try: for i in range(packet_size): code_word = b''.join( struct.pack("B", ii) for ii in mat_arr_code[:, i]) # bytes source = coder.decode(code_word, erasures_pos=errpos)[0] # list str source = [ii for ii in source] if len(source) < k: mat_arr_orig[0:(k - len(source)), i] = [0 for ii in range(k - len(source))] mat_arr_orig[(k - len(source)):, i] = [ord(ii) for ii in source] else: mat_arr_orig[:, i] = [ord(ii) for ii in source] except Exception, e: print(e.message)